| name | ios-game-feel-design |
| description | Add game-feel-inspired motion, impact, sound, haptics, celebration, and responsive feedback to iOS apps built with SwiftUI or UIKit. Use when designing or reviewing an iPhone/iPad app that should feel more tactile, lively, satisfying, or game-like, or when auditing an existing project to improve taps, gestures, repeated game actions, transitions, success states, errors, counters, onboarding, rewards, and other interactions. |
iOS Game Feel Design
Turn game-feel thinking into iOS-native product design. Favor implementations that are realistic in SwiftUI or UIKit, feel premium in an app context, and stay compatible with performance, accessibility, and platform norms.
Core Goal
Make actions feel acknowledged, readable, and satisfying without making the app feel gimmicky.
Prioritize:
- tactile confirmation for important actions
- visual impact for state changes
- readable anticipation before consequential transitions
- small rewards for progress, completion, streaks, wins, and saves
- motion that clarifies interaction instead of distracting from it
Example Requests
Use this skill for requests like:
- audit this SwiftUI app and list where game feel would help most
- review this UIKit screen and suggest iOS-native haptics and motion
- inspect this project and give me a numbered list of game-feel upgrades I can choose from
- make this onboarding or success flow feel more rewarding
- add subtle camera shake, impact, or celebration to this milestone state
Workflow
1. Inspect before suggesting
When working on an existing project:
- inspect the current screens, interaction points, and major user flows
- identify where feedback is missing, weak, delayed, or visually flat
- focus on moments that matter to users rather than adding motion everywhere
Audit these categories first:
- primary button taps and presses
- toggle, picker, tab, and segmented-control changes
- drag, swipe, reorder, and gesture completion
- save, submit, sync, refresh, import, and export flows
- success, warning, error, empty, and loading states
- navigation transitions, sheets, full-screen covers, and hero moments
- counters, streaks, progress rings, badges, rewards, and milestones
- onboarding reveals and first-time wins
2. Build a candidate list
After reviewing the app, present a short option list before implementing broad changes. For each candidate, include:
- location
- current issue
- proposed game-feel treatment
- APIs or techniques likely to be used
- effort level: low, medium, or high
- accessibility or platform risk
Use a compact format like:
| # | Area | Opportunity | Suggested feel | Likely APIs | Effort |
|---|
| 1 | Save button | Tap feels flat | press scale + soft impact haptic + success pulse | withAnimation, sensoryFeedback | Low |
Then ask the user which numbered items they want implemented. If the request is clearly for a single change, proceed directly.
3. Keep proposals iOS-feasible
Prefer native or app-appropriate techniques:
- SwiftUI animation APIs
- UIKit animation and Core Animation
sensoryFeedback when available
UIImpactFeedbackGenerator, UISelectionFeedbackGenerator, UINotificationFeedbackGenerator
CoreHaptics only when richer haptics are justified
- symbols, gradients, particles, blur, scale, offset, spring, opacity, and number transitions
Avoid suggesting game-only techniques that are awkward in normal apps unless the product truly wants a playful style.
4. Design the feedback event before the effect
For repeated interactions or playable loops, define the semantic event and its outcome before attaching animation, sound, or haptics. Examples include released, correct, perfect, rejected, milestone, and failed.
Keep durable product state separate from one-shot presentation events. When the same event can happen consecutively, pair the event payload with a monotonically increasing sequence, UUID, or other occurrence token so SwiftUI, SpriteKit, or SceneKit can react every time instead of only when an equatable value changes.
Use references/advanced-feedback-orchestration.md when implementing repeated game actions, multimodal timing, result sequences, tutorial demonstrations, or hybrid SwiftUI/rendering-engine screens.
Design Principles
1. Impact
Translate hits and collisions into app moments:
- button confirmation
- drop completion
- card snap-in
- streak increment
- purchase or unlock success
Use brief scale, spring return, glow, flash, burst, or haptic punctuation.
2. Anticipation
Let users feel important actions coming:
- button depress before trigger
- drag item stretching slightly before release
- sheet content easing in after background dim
- success reveal with a tiny setup beat before celebration
3. Clarity
Game feel must improve comprehension:
- winning state should look unmistakably different from idle
- invalid actions should feel blocked, not broken
- loading should communicate momentum, not just waiting
4. Reward
Use stronger feedback where user effort or emotional value is higher:
- completing onboarding
- hitting a goal
- saving something meaningful
- clearing a task list
- maintaining a streak
5. Rhythm
Combine fast primary feedback with slightly delayed secondary feedback:
- tap -> immediate scale/haptic
- 80-180ms later -> glow, badge pop, number roll, particle accent
This layered response often feels more alive than one large animation.
6. Escalation
Build an intensity ladder instead of treating every positive or negative outcome alike:
- neutral selection -> quiet visual change, optional selection tick
- successful action -> snap or settle, light/medium impact, short sound
- high-quality or perfect action -> stronger focal pulse, heavier impact, brighter sound
- milestone or recovery -> success haptic, distinct flourish, brief anticipation
- recoverable miss -> localized rejection, warning feedback
- terminal failure -> stronger failure treatment after the causal impact lands
Reserve the top of the ladder so it remains meaningful. A perfect action should not feel identical to a routine correct action, and a recoverable mistake should not sound or feel terminal.
iOS Pattern Palette
Reach for these patterns first:
- Press response: scale to
0.96-0.98, brighten or darken slightly, then spring back
- Snap response: offset or rotation settles with spring damping
- Camera shake: brief container-level shake for impact, collision, lock-in, or dramatic completion moments
- Success pulse: scale up then settle, optional ring or glow
- Number excitement: animate count changes with
contentTransition(.numericText()) or UIKit label transition
- Celebration burst: subtle particles, symbol bounce, confetti, or badge pop for milestones
- Error rejection: short horizontal shake, tint flash, warning haptic
- Card reveal: opacity + upward offset + stagger
- Selection lock-in: checkmark draw, fill expand, or symbol bounce
- Pull-to-refresh reward: progress morphs into success feedback when done
- Drag completion: hover lift while dragging, snap + haptic on drop
- Event pulse: semantic event payload + occurrence token so identical consecutive outcomes replay reliably
- Quality ladder: progressively stronger scale, glow, haptic, and sound for good -> perfect -> milestone
- Impact landing: delay secondary sound/haptic until a projectile, card, or moving object reaches its visual collision point
- Payoff gate: reveal the result, play the reward sequence, then enable buttons so taps cannot skip or collide with the payoff
- Guided affordance: briefly self-demonstrate a drag or press, but cancel immediately on user interaction
- Ambient layer: keep low-contrast, non-interactive motion separate from event-driven feedback and pause expensive loops when inactive
Use references/ios-implementation-patterns.md when you need implementation-oriented guidance.
Haptics Guidance
Treat haptics like punctuation, not background noise.
Preferred mapping:
- light selection ->
UISelectionFeedbackGenerator
- soft confirmation ->
.light or .soft impact
- heavier completion ->
.medium, .rigid, or notification success
- warning/error -> notification warning/error
- richer bespoke feel ->
CoreHaptics with device support checks
Rules:
- never spam haptics on every frame or repeated scroll tick
- align haptic timing with the visual peak, not with setup delay
- degrade gracefully on unsupported hardware
- respect user/device settings and avoid making core comprehension depend on haptics
For repeated game events, trigger from an occurrence token and conditionally choose the haptic from the semantic payload. Do not trigger only from a cumulative score when a reset, duplicate value, or non-scoring event could make the mapping ambiguous.
For countdown or urgency pulses, start only inside a short threshold window, stop on pause/background/completion, and avoid continuous vibration.
Sound Guidance
Treat short sound effects as part of the feedback system rather than sprinkling playback calls throughout views.
Prefer:
- semantic names such as selection, correct, wrong, impact, reward, and failure
- a centralized playback service that prewarms frequent sounds
- per-effect cooldowns so rapid repeated events do not create noise or clipping
- audio-session behavior that fits the product, often mixing with other audio for short interface sounds
- delayed playback for effects whose visual impact happens after travel or anticipation
- intensity that matches event frequency and consequence
Use quiet, short sounds for frequent inputs. Reserve arpeggios, multi-note cues, bassy impacts, and longer rewards for milestones or terminal outcomes. Sound, haptics, and animation should remain individually understandable when either of the other channels is unavailable.
Camera Shake
Use camera shake sparingly as a container-level emphasis effect. In app design, it should feel like a quick impact accent, not like a game camera constantly rattling.
Good fits
Use a light camera shake for:
- completing a dramatic milestone or reward reveal
- locking a dragged card or object into place
- strong success or failure moments with emotional weight
- simulated impact moments such as slam, collision, breakthrough, or countdown finish
- playful apps that intentionally lean into arcade, fitness, streak, habit, music, or creator energy
Treat it as a screen, panel, or card-group effect. Prefer shaking the relevant container rather than the entire app window.
Avoid when
Do not use camera shake for:
- routine taps that happen many times per session
- finance, medical, legal, or other high-trust flows where drama can feel careless
- text-entry flows, forms, or reading-heavy screens where motion hurts legibility
- long or repeated background processes
- moments where Reduce Motion users would lose clarity
If the same feedback can be communicated with scale, glow, or haptics alone, prefer those first.
SwiftUI approach
In SwiftUI, apply shake to a parent container with a transient x/y offset or a short keyframe sequence.
Preferred techniques:
keyframeAnimator for a tight left-right-left settle
phaseAnimator for a simpler staged shake
- a transient state variable driving
.offset
- combine with a very short scale pulse on the focal element, not on the whole container
Guidelines:
- keep duration around
120-220ms
- keep amplitude modest, usually
4-12pt
- decay each step so the shake settles quickly
- favor horizontal shake for rejection and impact, radial or mixed-axis shake only for highly playful apps
UIKit approach
In UIKit, shake a containing view with CAKeyframeAnimation on transform.translation.x or use a short UIViewPropertyAnimator sequence.
Preferred techniques:
CAKeyframeAnimation with decaying values like 0, 8, -6, 4, -2, 0
UIViewPropertyAnimator for coordinated shake plus scale or blur changes
- apply the motion to the affected panel, card stack, or content group instead of the whole root controller view unless the moment is intentionally cinematic
Pairing with haptics
The shake should peak at the same moment as the tactile hit.
Recommended pairings:
- light impact moment -> small shake +
.light or .soft impact
- lock-in / snap moment -> small shake +
.rigid or .medium impact
- strong success -> tiny shake or bounce + notification success
- failure / blocked action -> short shake + notification warning or error
Timing rules:
- fire the haptic at the first impact peak, not after the shake finishes
- do not stack multiple haptics for one small shake
- if the shake is stronger, keep the haptic simpler
- if haptics are unavailable, the shake should still read clearly on its own
SwiftUI Guidance
Prefer modern SwiftUI-first techniques when available:
withAnimation with spring timing for presses, snaps, and rewards
symbolEffect for SF Symbols emphasis
sensoryFeedback for native haptic triggers
contentTransition(.numericText()) for counters and streaks
matchedGeometryEffect for continuity between states
phaseAnimator or keyframeAnimator for layered feel moments
scrollTransition for tasteful list/card emphasis
Canvas or lightweight particle views for celebration moments
When reviewing SwiftUI code:
- check if state changes already exist and can drive animation cleanly
- prefer state-driven animation over imperative chains
- avoid stacking too many simultaneous modifiers that fight each other
- use cancellable
.task(id:) timelines for staged effects, and check cancellation after sleeps
- disable hit testing until a blocking reward or result entrance is ready when premature taps would break the sequence
UIKit Guidance
Prefer UIKit-native tools when working outside SwiftUI:
UIViewPropertyAnimator for interruptible motion
- spring animations for press, release, and snap-back
CAKeyframeAnimation for shakes, bursts, and emphasis
CASpringAnimation for physical rebound
CAEmitterLayer for lightweight celebratory particles
- haptic generators for interaction punctuation
Keep UIKit implementations coordinated with existing interaction handlers and view lifecycle.
SpriteKit and SceneKit Guidance
Use SpriteKit or SceneKit when a playable surface materially benefits from dense particles, many independently animated nodes, 3D perspective, or renderer-owned collision choreography. Keep surrounding navigation, HUD, sheets, and result UI in SwiftUI when practical.
Pass two kinds of data across the boundary:
- a snapshot for durable scene state
- a semantic event plus occurrence token for one-shot effects
On synchronization, rebuild only when identity or layout changes. Otherwise apply a one-shot effect only when the event token advances. Remove or replace keyed actions before replaying shakes or impacts, clean up temporary particles/nodes, and pause gameplay plus renderer-owned loops when the scene becomes inactive.
Project Review Output
When the user asks for an audit or you infer they want one:
- review the current project structure and relevant UI files
- identify the top 5-10 best game-feel opportunities
- rank them by user value and implementation cost
- present them as selectable options
- wait for the user to choose, unless they explicitly asked for direct implementation
For each recommendation, include:
- what the user currently experiences
- what would feel better
- why it helps
- the likely implementation surface in SwiftUI or UIKit
- any accessibility or performance caveat
Guardrails
Always preserve platform fit:
- respect Reduce Motion
- keep playful motion optional or toned down in serious/high-trust flows
- avoid long blocking animations on frequent actions
- avoid fake physics that slows expert users down
- do not vibrate for neutral events unless the product explicitly wants that personality
- make sure success and error states still read with sound and haptics disabled
- under Reduce Motion, compress staged reveals into an immediate readable end state instead of merely slowing the same choreography
- cancel automated affordance demonstrations as soon as the user interacts
If the app has a settings surface or a strong brand personality, consider proposing:
- reduced motion mode
- haptics toggle
- "celebrations" or "delight" toggle for high-energy feedback
Positioning Language
When presenting ideas, frame them as product improvements, not decoration:
- "make save feel confirmed"
- "make streak progress feel earned"
- "make invalid actions feel clearly rejected"
- "make navigation transitions feel connected"
Do not pitch motion as ornament first.