Game Feel · Design
Coyote Time, Input Buffers & the Small Lies That Make Platformers Feel Fair
Players don't want physics. They want the game to agree with what they meant. Here are the four timing cheats we ship in every platformer, and the frame counts we start from.
Every platformer that feels good is quietly lying to you. When you sprint off a ledge and press jump a heartbeat too late, the game lets you jump anyway. When you mash jump just before landing, it remembers. None of this is realistic; all of it is fair, because it matches what your hands intended rather than what the collision box measured.
I call these the small lies. After eleven years of tuning them on two console platformers and a pile of jam games, I've stopped treating them as polish and started treating them as foundations. These are the four I add on day one, before a single level exists.
1. Coyote time: 6 frames
Named after a certain cartoon canine who runs off cliffs and hangs in the air until he looks down. When the player leaves the ground without jumping, keep a timer running and accept a jump until it expires. At 60 fps we start at 6 frames (100 ms) and rarely go above 8; any longer and players feel the floor extending under them.
if grounded: coyote = COYOTE_FRAMES
else: coyote = max(coyote - 1, 0)
if jump_buffer > 0 and coyote > 0:
velocity.y = JUMP_SPEED
coyote = 0
jump_buffer = 0
2. Jump buffering: 7 to 9 frames
The mirror image. If jump is pressed slightly before landing, store it and fire it on the first grounded frame. Without a buffer, fast players experience "eaten" inputs and blame themselves, which is the worst kind of frustration because they can't put it into words.
3. Variable jump height
Release jump early and cut upward velocity. We multiply by 0.45 rather than zeroing it, which avoids the feeling of headbutting an invisible ceiling. One button now gives you short hops and full jumps, and your level designers can rely on exactly two arc heights.
4. Corner correction
When the player's head clips the corner of a ceiling tile by four pixels or fewer, nudge them sideways instead of killing the jump. Nobody ever notices it working. Everybody notices it missing.
One rule binds all four: count frames, not milliseconds, and only once your timestep is fixed. If it isn't fixed, fix that first. There's a note on why in The Wire below.