~1 min read

The Game Loop

How Phaser 4 schedules update and render, what delta means, and how to write frame-rate-independent code.

Every frame, Phaser does roughly this:

  1. Drain the input queue (pointer, keyboard, gamepad events received since the last frame).
  2. Call each active scene’s update(time, delta).
  3. Step the physics world.
  4. Render the display list to the canvas.

time is a monotonic millisecond timestamp; delta is the milliseconds elapsed since the previous frame.

Frame-rate independence

The single most important rule:

Multiply movement and rates by delta, not by a constant.

// Wrong — at 144fps your sprite moves 2.4× as fast.
sprite.x += 5;

// Right — speed is "pixels per second", independent of framerate.
sprite.x += 200 * (delta / 1000);

This applies to physics velocities you set manually, animation timers, particle emission rates, and anything else expressed as “per second.”

Fixed timestep vs. variable timestep

Phaser uses a variable timestep by default — delta reflects what actually happened. For deterministic simulation (lockstep multiplayer, recorded replays), use a fixed-step loop inside update:

private accumulator = 0;
private readonly STEP = 1000 / 60;

update(_time: number, delta: number) {
	this.accumulator += delta;
	while (this.accumulator >= this.STEP) {
		this.tick(this.STEP);
		this.accumulator -= this.STEP;
	}
}
  • Scenes — where the per-frame update lives.
  • Physics guides for how the physics world is stepped relative to the main loop.