---
key: lesson/game-loop
type: lesson
id: game-loop
lang: en
title: The game loop and time
summary: >-
  Separate simulation speed from frame rate and verify pauses, frame drops, and
  focus changes.
updatedAt: '2026-10-20'
status: active
url: 'https://gamemechanics.pro/en/lessons/game-loop/'
jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/lesson/game-loop.json'
markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/lesson/game-loop.md'
aliases: []
tags:
  - game-loop
  - time
  - simulation
sourceIds:
  - source-4794cbcf5206cc3d
  - source-61d9bfebd277d850
  - source-e55fb78e3762cd48
sources:
  - id: source-4794cbcf5206cc3d
    title: 'Robert Nystrom: Game Loop'
    url: 'https://gameprogrammingpatterns.com/game-loop.html'
    verifiedAt: null
  - id: source-61d9bfebd277d850
    title: 'MDN: requestAnimationFrame'
    url: >-
      https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame
    verifiedAt: null
  - id: source-e55fb78e3762cd48
    title: 'Glenn Fiedler: Fix Your Timestep!'
    url: >-
      https://github.com/mas-bandwidth/gafferongames/blob/main/content/post/fix_your_timestep.md
    verifiedAt: null
relations:
  - type: requires
    direction: outgoing
    label: Before you start
    key: lesson/scope-and-prototype
    title: Scope and a testable prototype
    url: 'https://gamemechanics.pro/en/lessons/scope-and-prototype/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/lesson/scope-and-prototype.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/lesson/scope-and-prototype.md
  - type: requires
    direction: incoming
    label: Continue learning
    key: lesson/input-and-feedback
    title: Input and feedback
    url: 'https://gamemechanics.pro/en/lessons/input-and-feedback/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/lesson/input-and-feedback.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/lesson/input-and-feedback.md
  - type: requires
    direction: incoming
    label: Continue learning
    key: lesson/collision-basics
    title: Collision fundamentals
    url: 'https://gamemechanics.pro/en/lessons/collision-basics/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/lesson/collision-basics.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/lesson/collision-basics.md'
  - type: requires
    direction: incoming
    label: Continue learning
    key: lesson/performance-budget
    title: A performance budget
    url: 'https://gamemechanics.pro/en/lessons/performance-budget/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/lesson/performance-budget.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/lesson/performance-budget.md
  - type: contains
    direction: incoming
    label: Learning paths
    key: path/first-prototype
    title: Your first verifiable prototype
    url: 'https://gamemechanics.pro/en/learn/first-prototype/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/path/first-prototype.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/path/first-prototype.md'
  - type: requires
    direction: incoming
    label: Continue learning
    key: path/npc-behavior
    title: NPC behavior
    url: 'https://gamemechanics.pro/en/learn/npc-behavior/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/path/npc-behavior.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/path/npc-behavior.md'
  - type: uses
    direction: outgoing
    label: Sources in the selection
    key: resource/game-loop-pattern
    title: 'Game Loop: Game Programming Patterns'
    url: 'https://gamemechanics.pro/en/resources/#resource-game-loop-pattern'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/resource/game-loop-pattern.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/resource/game-loop-pattern.md
  - type: uses
    direction: outgoing
    label: Sources in the selection
    key: resource/animation-frame
    title: requestAnimationFrame on MDN
    url: 'https://gamemechanics.pro/en/resources/#resource-animation-frame'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/resource/animation-frame.json
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/resource/animation-frame.md'
  - type: uses
    direction: outgoing
    label: Sources in the selection
    key: resource/fixed-timestep
    title: Fix Your Timestep!
    url: 'https://gamemechanics.pro/en/resources/#resource-fixed-timestep'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/resource/fixed-timestep.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/resource/fixed-timestep.md'
placements: []
supersededBy: []
attributes:
  category: foundations
  level: beginner
  minutes: 6
endsAt: null
provenance: >-
  Original gamemechanics.pro material. Check illustrative examples in your own
  project.
license: CC-BY-4.0
codeLicense: MIT
attribution: gamemechanics.pro contributors
---
# The game loop and time

id: game-loop
type: lesson
key: lesson/game-loop
lang: en
status: active
url: https://gamemechanics.pro/en/lessons/game-loop/

Separate simulation speed from frame rate and verify pauses, frame drops, and focus changes.

## Prerequisites

You only need variables, functions, and coordinates. By the end, you should be able to identify what updates the world, state the units of movement speed, and explain why a rendered frame is not necessarily one simulation step.

## The principle

A game loop connects input, state updates, and presentation. The world can keep changing while the player stands still. An engine already owns this loop; connect your behavior to its appropriate update callbacks. [Game Loop](https://gameprogrammingpatterns.com/game-loop.html) explains this basic model.

The expression `x += 3` moves three units per call. More calls therefore produce more movement. The expression `x += speed * dt` describes movement through elapsed time, with speed in units per second and `dt` in seconds. This does not make every physics simulation stable for arbitrary time steps.

A simulation sensitive to step size can use a fixed update interval. Accumulated real time is consumed in equal simulation steps, while rendering happens independently. Limiting catch-up steps requires a deliberate overload policy, such as letting simulation time fall behind. [Fix Your Timestep!](https://github.com/mas-bandwidth/gafferongames/blob/main/content/post/fix_your_timestep.md) explores that tradeoff.

<span id="a-concrete-exercise"></span>

## Practical example

### A concrete exercise

Start with one square and no collisions. Give it a speed of 120 units per second. After two seconds of uninterrupted movement, it should travel 240 units, regardless of how many frames were displayed.

```text
update(dtSeconds, input):
    if input.moveRight:
        player.x += 120 * dtSeconds

render():
    drawSquare(player.x, player.y)
```

This is teaching pseudocode, not a complete engine loop. Call `update` 120 times using `1/60`, then run a fresh case with 60 calls using `1/30`. Compare final positions with a small numerical tolerance. Finally, try uneven intervals whose sum is still two seconds.

In a browser, `requestAnimationFrame` schedules a callback (a function run by the browser) before repainting and normally pauses in background tabs. Its timestamp uses milliseconds; see the [MDN reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame). Define a resume policy. For this exercise, discard the old timestamp when focus returns so that the square continues from a paused position.

## Common mistakes

Do not modify movement in both physics and presentation callbacks. Do not multiply by elapsed time twice when an engine method already handles it. Do not start another loop whenever the level restarts. Hiding a tab is also not a complete pause implementation: audio, network events, and timers may follow different lifecycles.

Check raw movement before introducing interpolation. Once the simulation is correct, add visual smoothing as a separate change. A smooth picture can otherwise conceal incorrect speed or update order.

## Verify it

- Equal simulation time produces equal travel at different update frequencies.
- Pausing stops the intended systems while keeping the menu usable.
- Returning from a background tab does not teleport the player.
- Restarting the scene does not double movement speed.
- Variable names or comments make time and speed units explicit.

## Prompt for an AI agent

> Locate the owner of the game loop and every place that changes player position. Explain the units of speed and elapsed time. Propose the smallest fix for frame-rate-dependent movement, then check travel over two seconds with several dt sequences. State pause and focus-resume behavior separately. Do not replace the physics backend without evidence that it is necessary.

## Connected materials

- Before you start: [Scope and a testable prototype](https://gamemechanics.pro/en/lessons/scope-and-prototype/) (key: lesson/scope-and-prototype)
- Continue learning: [Input and feedback](https://gamemechanics.pro/en/lessons/input-and-feedback/) (key: lesson/input-and-feedback)
- Continue learning: [Collision fundamentals](https://gamemechanics.pro/en/lessons/collision-basics/) (key: lesson/collision-basics)
- Continue learning: [A performance budget](https://gamemechanics.pro/en/lessons/performance-budget/) (key: lesson/performance-budget)
- Learning paths: [Your first verifiable prototype](https://gamemechanics.pro/en/learn/first-prototype/) (key: path/first-prototype)
- Continue learning: [NPC behavior](https://gamemechanics.pro/en/learn/npc-behavior/) (key: path/npc-behavior)
- Sources in the selection: [Game Loop: Game Programming Patterns](https://gamemechanics.pro/en/resources/#resource-game-loop-pattern) (key: resource/game-loop-pattern)
- Sources in the selection: [requestAnimationFrame on MDN](https://gamemechanics.pro/en/resources/#resource-animation-frame) (key: resource/animation-frame)
- Sources in the selection: [Fix Your Timestep!](https://gamemechanics.pro/en/resources/#resource-fixed-timestep) (key: resource/fixed-timestep)

## Sources and provenance

Original gamemechanics.pro material. Check illustrative examples in your own project.

- [Robert Nystrom: Game Loop](https://gameprogrammingpatterns.com/game-loop.html) (id: source-4794cbcf5206cc3d)
- [MDN: requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame) (id: source-61d9bfebd277d850)
- [Glenn Fiedler: Fix Your Timestep!](https://github.com/mas-bandwidth/gafferongames/blob/main/content/post/fix_your_timestep.md) (id: source-e55fb78e3762cd48)

CC-BY-4.0 · gamemechanics.pro contributors
