Game loop pattern
Decouple game progression from hardware speed by running input, update, and render in a controlled loop with fixed or variable time steps.
Introduction
The Game Loop pattern gives a real-time simulation a repeatable cycle: sample input, advance the simulation, and render the current state. Its timing policy determines how wall-clock time is converted into simulation time.
TL;DR / mental model: Treat simulation time and rendering time as separate clocks. The loop accumulates elapsed wall-clock time, advances the simulation in controlled steps, and renders as often as practical.
Problem and Context
You are building a 2D platformer. The character runs, jumps, and interacts with physics. You write a simple while(true) loop that reads input, updates positions, and draws every frame, as fast as the CPU allows.
On your dev machine the game feels perfect. On your tester's laptop it runs at half speed. On a gaming rig it runs double speed. Multiplayer is impossible because every client simulates differently. The root cause: update logic is coupled to frame rate, so game speed depends on hardware speed.
When It Helps
The pattern helps when simulation behavior should not depend on how quickly a machine renders frames, especially for physics, collision detection, replays, or real-time multiplayer. A simple variable-delta callback or a framework-provided loop may be enough for cosmetic animation and turn-based rules.
Here is what changes when you apply the Game Loop pattern.
Participants and Structure
Participants
- Game loop: owns the frame cycle, timing policy, accumulator, and update budget.
- Game or simulation: exposes input, update, render, and lifecycle operations without owning frame pacing.
- Clock: supplies elapsed time and isolates platform-specific timing for tests.
- Concrete game and subsystems: implement domain behavior such as player movement, physics, and drawing.
The GameLoop owns the timing. Game is a clean interface with three responsibilities: read input, advance simulation, and draw. Concrete games (like Platformer) implement those three methods without worrying about frame pacing, sleep, or time accounting. The Clock isolates platform-specific timing so the loop stays testable.
Idiomatic Example and Implementation Notes
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with SDEpedia Premium.
Related Articles
The state pattern encapsulates state-specific behavior into separate objects, eliminating large switch statements and making each state's logic independently testable.
The command pattern turns requests into objects so you can queue, log, and undo operations. Decouple sender from receiver by encapsulating actions.
The observer pattern decouples event producers from consumers. A subject notifies all registered observers of state changes without knowing who they are or what they do.