Game loop and delta time: How games run
In short: A game runs in an endless loop of reading input, updating state and drawing a frame; delta time makes it run at the same speed on fast and slow devices.
In more detail: Unlike an application that waits for clicks, a game has to keep running constantly, even if the player does nothing. The heart is the game loop.
In Depth
The three steps
while game is running:
input = read_inputs() # keys, mouse, controller
update(game_state, dt) # movement, physics, AI, rules
draw(game_state) # image on the screen
One pass is a frame. 60 passes per second give 60 FPS (frames per second), i.e. about 16.7 milliseconds per frame.
Delta time
Without time measurement a game runs faster on a fast computer. The solution: measure the time since the last frame (dt) and calculate with it:
let last = performance.now();
function loop(now) {
const dt = (now - last) / 1000; // seconds
last = now;
player.x += speed * dt; // pixels per second
draw();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);requestAnimationFrame calls the function in step with the monitor’s refresh rate and pauses in inactive tabs.
Fixed time steps
Physics and collision become unstable with a variable dt (objects “tunnel” through walls, jumps have different heights). Better: a fixed time step (for example 1/60 s) for logic, drawing runs separately. Collect elapsed time in an accumulator and run as many fixed steps as fit. Important is to clamp dt after long pauses (for example at most 0.25 s).
More notes
Separate logic and presentation, limit memory allocations in the loop (garbage collection can cause stutter), use object pools instead of constantly creating new objects, and measure with an FPS counter and profiler. Collect inputs first, then evaluate them in the logic.
See also: Game engine, Programming browser games, FPS, Latency