Skip to content
Michael Malura
570 GitHub stars 5810 npm downloads 53 Projects

Update loop

The simplest game loop fits in three lines: read input, update the game, draw a frame, start over. It runs as fast as the machine can. That is exactly the problem, because then everything depends on the speed of the machine.

The teal square moves at a fixed 60 updates per second, no matter how often frames are drawn. Both counters are at the top of the demo: updates/s stays at 60, frames/s follows your display.

Separating logic from drawing

The loop in the demo measures how much time has passed since the last iteration and puts it into a bucket, the accumulator. As long as the bucket holds at least one step of 1/60 second, a logic update runs and the bucket shrinks by one step. Drawing happens once afterwards:

frameTime = std::min(frameTime, 0.25);
accumulator += frameTime;
while (accumulator >= kStep) {
    update();
    accumulator -= kStep;
}
draw();

The clamp to 0.25 seconds has a reason. If the game stalls for a moment, the bucket would try to catch up hundreds of steps at once, the catching up takes too long itself, and the loop never recovers. The clamp limits the frame interval before it gets that far. What drawing looks like between two logic steps is in the post Fixed timestep. The alternative, where the step size grows with the frame time, is in Delta time.

The same thing in Python

The second demo is the same loop in Python with pygame-ce, running right in the browser through Pyodide. On first start it downloads about 15 MB of runtime, afterwards it comes from the cache. Dumb part: my first version ran the loop at over 2000 frames per second, because await asyncio.sleep(0) gives the browser no break. Now it sleeps briefly on every iteration (await asyncio.sleep(1 / 120)), and the logic still stays at 60 updates.

The step logic lives in a small class FixedStepper, covered by six unit tests. It knows neither pygame nor Pyodide, so it also runs natively in the tests.

Both demos are in the repo: C++ with SDL3 and Python with pygame-ce. The project Game Dev Snippets collects all demos of the series.

24.07.2026 updated 06.11.2026
Share X Reddit Hacker News LinkedIn E-Mail
Subscribe to new posts RSS JSON