Lifestyle & Tools
#game
game-feel
Tune how a game feels — input forgiveness, movement curves, hit stop, screen shake, squash and stretch, camera and audio feel — with concrete numbers.
DeepseekModel
Curated skill
Quality Excellent · 78
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=kyh-vibedgames-plugins-game-craft-skills-game-feel-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name game-feel description Tune how a game feels — input forgiveness, movement curves, hit stop, screen shake, squash and stretch, camera and audio feel — with concrete numbers. Game feel: the numbers Game feel = real-time control + simulated space + polish (Swink). The polish amplifies the simulation but never lies about it: if the screen shakes, something must have hit. Small tweaks compound — Vlambeer's flat shooter becomes Nuclear Throne via ~30 individually-invisible tricks. Apply them in passes, then play it : feel is tuned in motion, never designed on paper. All frame counts assume 60fps — which means physics must be delta-time-based . Per-frame integration ( x += vx ) runs 2× fast on a 120Hz display; this is the single most common feel bug in browser games. Multiply all motion by dt , and convert the frame windows below to ms when your loop isn't fixed-step. Never derive a bounce/return angle from penetration depth at the detection frame ( atan2(ball.y − paddle.y, …) ): depth ∈ (band − v·dt, band] is integration noise, so the same hit returns steep at 144 Hz and shallow at 30 Hz. Use the tangential offset only (x-offset across the face → linear angle curve), or back-project to the band-entry point first. Input forgiveness (the invisible half of "tight controls") Fudge everything slightly in the player's favor — players read forgiveness as their own skill (Celeste). Input buffer 4–10 frames : a jump/attack pressed slightly early fires on the first legal frame. Celeste ~4, Smash 10. Start at 5 for precise games, 8–10 for forgiving ones. Track a bufferedAt timestamp per action; consume in update() . Coyote time 5–8 frames : jump still works after walking off a ledge (Celeste ~5–6). Track lastGroundedAt . Corner correction : a jump that clips a ceiling corner by a few px gets nudged sideways; a dash that clips a ledge pops up onto it. Celeste's wall-jump reaches ~2px off the wall at 320×180 — scale to your resolution. Never demand frame-perfection. Any 1-frame window gets widened. Player hurtbox smaller than the sprite (Silksong, bullet hells): damage collision ~70–85% of the visual body. Near-misses that look like grazes should be grazes. Attack/interaction hitboxes go the other way — generous. Touch: enlarge hitboxes, not visuals — tappable region > sprite. Respond to core verbs within ~100ms total (Swink's correction cycle); never add startup delay to movement inputs. Continuous/tracking inputs (pointer, analog stick, webcam/hand): the forgiveness knob is smoothing-vs-latency. Lerp the controlled object toward the input (factor ~0.1–0.3 per 60fps frame) to kill jitter, but keep total lag under the ~100ms cycle; add a small dead zone, and fudge the interaction hitboxes (paddle/catch zones) larger than the visuals. Movement curves Reach max run speed in ~6 frames, stop in ~3 (Celeste). Stopping faster than starting reads "responsive"; the reverse reads "slippery". Variable jump height : releasing jump early cuts upward velocity. Apex float : while jump is held, halve gravity near the arc's peak (Celeste) — gives air-control where players need it. Fall faster than you rise : heavier gravity on descent + a fall-speed cap. Symmetric arcs feel floaty. Keep platform momentum for a few frames after leaving a moving platform. Phaser: implement as manual velocity writes in update() — Arcade drag alone can't express asymmetric accel or apex gravity. Personality is a palette, not one recipe : the numbers above tune "responsive", but a kit reads best through contrast — a tight, heavy base moveset plus ONE deliberately loose, momentum-carrying ability (a fling, a grapple, a slide) produces more joy than uniform tightness. Tune the outlier for arc and carry, not control. Movement depth & expression More depth never means more buttons. Three ways a move can be triggered: Button moves — few, foundational (jump, dash, attack). Context moves — the same button does something new given environment state: wall touch → wall jump, airborne over a bounce surface → bounce, moving on landing → slide. This is where depth is cheapest. Sequence moves — input chains: jump at the end of a grapple → fling, dash into a roll → extended roll. Reward timing, don't require it. Working method: Audit dead moments : anywhere the player is locked out of decisions (mid-grapple, mid-dash, mid-knockback), ask "what context or sequence could give them an option here?" Each option multiplies expression. Directional choices follow facing — fling/bounce direction = the way you face. Doubles as leniency: no separate aim input to fumble. Consistency beats physics : the same fling should work off floor, wall, and ceiling. Cross-move consistency is what lets players compose moves you never planned. Emergent chains appearing uninvited (roll → corner-fling → wall-bounce you never designed) are the success signal — keep them, build levels around them. Playtest-kill confusing moves even if you love them; keep a powerful move balanced by shrinking its effective range/window, not by weakening its feel. Impact Hit stop : freeze attacker AND victim 2–5 frames on light hits, 6–12 on kills, hard cap ~20–30 (Smash ≈ damage × 0.65 + 6 frames). Scale with importance. Pause tweens/anims for the parties, not the whole world, when multiple fights overlap. In non-Phaser loops (rAF/ useFrame ), implement as a freeze timer that skips integration for the frozen entities while rendering continues. Hit window ≠ animation length. Keep the hit early (~100ms into the cycle) for responsiveness and let the swing read slow; never tie the hit to a "make it look slower" multiplier. Pin the hit to the measured contact frame, compress windup, hold follow-through. Derive damage from duration ( dmg = round(dur × k) ) so slow kits hit harder and the DPS band stays level. Knockback both ways : victim recoils from hits; shooter kicks back 1–2px on fire. Suspend AI steering ~150ms so the shove reads. Hit flash : solid white tint 1–3 frames. Particles at every contact (muzzle, impact, dust on land), lifetimes 0.2–0.5s. Permanence : corpses, craters, shell casings stay (Nijman's highest-leverage trick). Stamp into a texture or cheap static images, not live bodies. Bigger projectiles, lower accuracy, higher fire rate — perfect accuracy reads sterile. Animation principles (Disney, applied) Squash & stretch, volume conserved : scale Y 0.7 on landing → scale X ~1.3. Stretch along velocity at speed; squash on impact. Typical: jump stretch 1.1–1.25, land squash 1.2–1.4, recover over 100–200ms ease-out. Anticipation on big actions only : 2–6 frame wind-up before a boss leap or charged shot. Never on core movement — that's input lag. Overshoot and settle : Back.easeOut / Elastic.easeOut on everything that appears or changes; stagger group entrances 20–50ms apart. Nothing pops : scale-in on spawn, shrink-and-fade on death. Camera Lerp-follow with look-ahead in the facing/aim direction. Phaser: startFollow(player, true, 0.08–0.15) + manual look-ahead offset. Trauma shake (Eiserloh): events add 0.2–0.5 to a 0–1 trauma value; decay to 0 over 0.5–1s; offset = maxOffset × trauma², sampled from smooth noise per axis. Add rotational shake (max ~5–10°) — cheapest way to make 2D shake feel violent. Maxima ~5–10% of screen size. Trauma stacks naturally where fixed-magnitude camera.shake() calls fight each other. Directional camera kick : punch a few px opposite the shot / into the hit, ease back. Distinct from omni shake. Keep shakes short (<0.5s). Offer reduce-motion for sustained shakers. Audio feel Every interaction sounds — fire, hit, kill, land, pickup, UI. Audio is half of juice and the cheapest half. Randomize pitch ±5–15% per play: sound.play({ rate: 0.9 + Math.random() * 0.2 }) . Lower pitch = heavier. Fatten kills/explosions with a bass layer; put a distinct confirm sound on kills above the routine hit sound. Duck or sting music on death/level-clear; silence after noise is itself an effect. Browser: unlock audio on first gesture; pool instances to avoid GC hitches. Web Audio double-stop throws : a source with stop(t) scheduled at creation throws on a second stop() — a forced release only disconnect() s. Face/pose-only players never fire the unlock gesture. Show a sound-hint pill while the context is locked; silence reads as a broken game. Tuning session Numbers above are starting points, not answers. Wire the 5–6 feel constants (accel frames, buffer, coyote, hit-stop, shake trauma) to a debug panel or query params, play 2 minutes, adjust, repeat. If you can't decide between two values, the larger forgiveness / smaller effect is usually right. When a target feel exists (e.g. "like Celeste", "like Downwell"), run the reference game side-by-side and A/B the same maneuver — match cadence and stop distances by eye and SFX timing by ear; memory of feel is unreliable. Related skills: game-playbook (build order + basic craft pass), phaser (engine APIs), onboarding (difficulty feel), design-lenses (is it fun at all).
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.