The Game Loop & Delta Time
The heartbeat of every game — how the update/render loop works and why delta time keeps movement consistent across frame rates.
Every game, under the hood, is a loop that runs many times per second: read input, update the world, draw it, repeat. This game loop is the heartbeat of your game — and understanding it (plus one concept called delta time) fixes a whole class of bugs.
The loop
Each iteration is a frame, and each frame does roughly:
- Input — what did the player press?
- Update — advance the simulation: move things, run AI, check collisions.
- Render — draw the current state to the screen.
Do this 60 times a second and you have smooth, interactive motion. Most engines run this loop for you and just call your update() and render() functions each frame.
The problem: frame rates vary
Here's the trap. If you move a character "5 pixels per frame," it moves at different real-world speeds on different machines — twice as fast at 120 FPS as at 60 FPS. Frame rate isn't constant (it dips under load, varies by hardware), so per-frame movement makes your game run at inconsistent speeds. That's a bug.
The fix: delta time
Delta time (dt) is how long the last frame took, in seconds. Instead of moving per frame, you move per second and multiply by dt:
position += speed * dt
Now "speed" means units per second, and it's the same whether the game runs at 30, 60 or 144 FPS — because a slower frame has a bigger dt that exactly compensates. Any value that changes over time — movement, timers, animations, cooldowns — should be scaled by delta time.
Fixed timestep for physics
There's a catch: physics and collisions can behave differently with variable dt (a huge lag spike makes objects jump far and tunnel through walls). For stable simulation, many games use a fixed timestep — the update runs in constant-size steps (e.g. 1/60s) regardless of render rate, so physics stays deterministic while rendering can still vary. It's why engines separate update (fixed) from render (every frame).
Mental model
The game loop is input → update → render, forever. Multiply anything time-based by delta time so it runs at the same speed everywhere, and use a fixed timestep when physics needs to stay stable. Get this right and your game feels consistent on every machine.