How 2D Platformer Physics Work (The Hidden Math)

high rise buildings during night time

2D platformer physics look obvious from outside — gravity pulls the character down, the jump button makes them go up. The reality is much busier. Every good platformer is a stack of small tricks: variable jump height, coyote time, jump buffering, fixed timestep integration, and a dozen others. None of these are realistic physics. They’re carefully tuned approximations that make the game feel responsive and fair. Here’s what’s actually running under the hood.

Key takeaways

  • Variable jump height lets the player control jump arc by how long they hold the button.
  • Coyote time gives the player a brief grace period to jump after stepping off a ledge.
  • Jump buffering lets the game accept a jump input slightly before the character lands.
  • Fixed timestep integration ensures consistent physics regardless of frame rate.
  • None of these tricks are “real” physics — they’re feel-tuned approximations.

The basic equations

The simplest platformer physics use two variables per character: position (x, y) and velocity (vx, vy). Each frame, gravity adds a constant to vy (the character accelerates downward), and the character’s position updates by its velocity. The jump button sets vy to a large negative value, which propels the character upward against gravity.

That’s it for the core. Everything else is refinement.

Variable jump height

Hold the jump button longer for a bigger jump. Every good platformer has this. The implementation is simple: while the button is held and the character is moving upward, gravity is reduced (often by half). When the button releases, gravity returns to normal, which cuts the rise short.

Mario does this. Sonic does this. Hollow Knight, Celeste, every modern platformer does this. The reason is feel — without variable jump height, every jump is a fixed parabola, and the player has no fine control. With it, the player can tap for a small hop or hold for a tall arc, and the input feels rich.

Some implementations clip the upward velocity instead of changing gravity — when the button releases, vy is multiplied by a value less than 1 (like 0.5). Both approaches work; gravity modulation is more common in physics-driven engines, velocity clipping in simpler ones.

Coyote time

Named after Wile E. Coyote, who pauses mid-air before falling, coyote time gives the player a brief window — usually 80 to 150 milliseconds — after walking off a ledge during which a jump input still counts as a ground jump.

Without coyote time, players who press jump a frame or two after stepping off a ledge fall straight down. With coyote time, the jump registers. The character “should” be falling but the game pretends they’re still on the ground for a few frames.

The implementation is a small timer that starts when the character leaves the ground and is checked at jump input. If the timer is below the coyote threshold, treat the input as a grounded jump. This single mechanic accounts for a huge fraction of the perceived “feel” difference between cheap platformers and polished ones.

Jump buffering

The mirror image of coyote time. Jump buffering accepts a jump input slightly before the character lands — usually within 100 to 150 milliseconds of landing. Without it, players who press jump just before hitting the ground get nothing; with it, the input queues and fires the instant the character touches down.

Together, coyote time and jump buffering produce a roughly 200-millisecond window of forgiveness around every jump. The combined effect is that “I pressed jump and the game should have responded” almost never happens. Inputs that look like they should work usually do.

Fixed timestep integration

If your physics update every rendered frame, your physics depend on frame rate. A character that jumps to a height of 3 tiles at 60 FPS will jump to 1.5 tiles at 120 FPS, because gravity got twice as many ticks to pull down. That breaks the game.

Fixed timestep integration solves this by separating the physics tick from the render tick. The physics loop runs at a fixed rate — 60 ticks per second is common — regardless of how fast the renderer is going. If the renderer is faster, it interpolates between physics ticks. If slower, the physics loop catches up by running multiple ticks per render frame.

This is the standard approach, popularized by Glenn Fiedler’s “Fix Your Timestep” essay from the 2000s. Every serious game engine implements some version of it. Without it, physics behavior changes with frame rate, and tight platformers become unplayable on hardware they weren’t tuned for.

Collision detection and resolution

Platformers usually use AABB (axis-aligned bounding box) collision, the same approach the Chrome Dino game uses, with extensions for slopes and one-way platforms. The character is a rectangle, the world is rectangles, and intersection is detected by the four-comparison test.

Resolution is more interesting. When the character collides with a wall, the engine has to decide what to do. The standard approach is “swept AABB”: cast the character’s movement vector as a ray and find the first surface it hits, then place the character flush against that surface and zero out the velocity component perpendicular to it. Walls stop horizontal velocity; floors stop downward velocity.

One-way platforms (you can jump up through them but stand on top) are handled by skipping the collision check when the character’s velocity is upward. Slopes are typically handled by tilting the resolution direction along the slope’s normal.

Acceleration and deceleration

Movement isn’t instantaneous in good platformers. Press right, and the character accelerates over a few frames to top speed. Release, and they decelerate. The acceleration and deceleration rates are tuning parameters that change the game’s feel dramatically.

Mario’s air control is famously different from his ground control. He accelerates faster on the ground than in the air, which means mid-jump direction changes are limited but possible. Celeste’s wall jumps come with a brief lockout of horizontal input control to prevent immediate wall-sticking. These are all tuning decisions.

A common pattern is to have separate ground and air acceleration values, plus a “skid” multiplier when the player presses the opposite direction from current velocity. The skid multiplier makes 180-degree turns feel snappy.

Terminal velocity and falling

Without a velocity cap, characters accelerate forever in long falls. The cap — terminal velocity — is usually 8 to 12 tiles per second downward. The cap keeps falls predictable and prevents the character from clipping through floors at high speed (a common bug when downward velocity exceeds the collision check granularity).

Some games tune terminal velocity to match a deliberate “max useful drop height,” giving the player a feel for how far they can safely descend.

The hidden invisible ledge

Many platformers extend ledges visually past where the collision actually ends — or, the opposite, extend the collision past where the visual ends. The trick is to make jumps that look impossible actually clear, or to make jumps that look risky actually safe. Mario 64’s distant ledges and Celeste’s tight corners both use variants of this.

The implementation is a “ledge nudge” — when a jumping character is within a pixel or two of a ledge, the engine snaps them onto the ledge instead of letting them clip past. The pixel difference is invisible to the player; the gameplay benefit is significant.

Why none of this is “real” physics

Real physics would have characters accelerate from gravity (9.8 m/s^2), have realistic mass and friction, and not let you control mid-air motion. None of that is fun. Mario can’t be Mario in real physics. Good platformer physics are tuned for game feel, not realism.

The trade-off is intentional. Realistic 2D platformers exist (Limbo’s character animation has some weight to it) but they’re rare. Most platformers go in the other direction — exaggerated air control, instant directional change, jumps that are 4x the character’s height. Real physics would kill the genre.

For browser platformers that get the feel right, see our roundup of best browser platformer games.

Frequently asked questions

What is coyote time in a platformer?

Coyote time is a brief grace period — usually 80 to 150 milliseconds — after a character steps off a ledge during which a jump input still counts as a ground jump. It compensates for slightly late jump presses and is standard in modern platformers.

What is jump buffering?

Jump buffering accepts a jump input that comes slightly before the character lands. If the player presses jump within roughly 100 to 150 milliseconds of touching the ground, the input fires as soon as they land. It pairs with coyote time to create a forgiving input window around every jump.

Why do platformers use fixed timestep physics?

So physics behavior doesn’t change with frame rate. If you tied physics to rendered frames, a 120 FPS player would jump half as high as a 60 FPS player. Fixed timestep decouples physics from rendering and keeps the game consistent across hardware.

How does variable jump height work?

While the jump button is held and the character is moving upward, gravity is reduced (or velocity is preserved). When the button releases, gravity returns to normal, cutting the jump short. The longer the hold, the higher the jump.

Are platformer physics realistic?

No. Platformer physics are tuned for feel, not realism. Air control, exaggerated jump heights, instant direction changes, and ledge nudges are all unrealistic but make the genre work. Real physics would make platformers unplayable.

The takeaway

Every good 2D platformer is built on a small library of feel tricks — coyote time, jump buffering, variable jump height, fixed timestep, ledge nudges, and acceleration curves. None of them are physics. All of them are why the game feels right. The hidden math of platformers isn’t elegant — it’s a pile of forgiving heuristics, and that pile is what separates a polished game from a frustrating one.