Skip to content
Lesson 1 of 14

Step 1 of 5 · Reading · ~4 min

Read

Math & Integration

What Physics Engines Solve

A rigid-body engine answers one question over and over: given where every body is and how fast it moves, where is each one a moment later, and which of them now touch? After this lesson your program will run the heartbeat of that loop: it turns the uneven frame times a game produces into a steady series of fixed physics steps, without losing time and without inventing any.

The pipeline you will build

One engine step is a fixed sequence of stages. Each later lesson in this course builds one of them:

forces -> integrate -> broad phase -> narrow phase -> solve contacts and joints -> sleep idle bodies
  • Integrate: forces change velocities, velocities change positions (Newton: F = m a).
  • Broad phase: cheaply list the pairs of bodies that might touch.
  • Narrow phase: test each candidate pair exactly and describe the contact.
  • Solve: change velocities (impulses) and positions so bodies bounce, slide or rest instead of overlapping.

Real engines (Box2D, Bullet, PhysX, Havok, Rapier) have exactly these stages. By the last lessons you will step a small world through all of them.

Why every step has the same length

The step advances the world by dt seconds. If dt changed from frame to frame, three things would break:

  • Determinism. The same inputs would give different results on a fast and a slow machine, so replays, tests and lockstep networking all stop working.
  • Stability. A spring that behaves at 16 ms can explode at 50 ms, because integration error grows with the step.
  • Tunnelling. A body moves further per step when the step is longer, so thin walls get skipped more often.

So physics advances in fixed steps (say 20 ms, i.e. 50 Hz) however fast or slow the renderer runs.

The accumulator

Frames arrive with irregular elapsed times. Keep a bank of time that has passed but has not yet been simulated. Add each frame's elapsed time to the bank, then spend it in coins of exactly dt.

Trace with dt = 25 ms and four frames of 40, 10, 60 and 5 ms:

elapsed   bank before   steps   bank after
   40          40         1         15
   10          25         1          0
   60          60         2         10
    5          15         0         15

The leftover is never thrown away. It stays in the bank and is spent when enough time has accumulated. Note the second row: a bank of exactly dt buys a step now.

The render fraction

After spending, the bank holds a value from 0 up to (but not including) dt. Divided by dt it gives a fraction alpha in [0, 1): how far the displayed moment lies between the last two simulated states. A renderer draws each body at previous * (1 - alpha) + current * alpha. Without it, a frame that runs 0 steps followed by one that runs 2 makes motion visibly stutter.

The spiral of death

Suppose one step costs more real time to compute than the dt it simulates. The next frame is then longer, so it needs more steps, so it takes even longer, and the game freezes. The standard fix is to clamp the elapsed time you accept per frame (for example 100 ms). The simulation then falls behind the wall clock, which looks like slow motion instead of a hang.

Common mistakes

  • Running at most one step per frame. A 60 ms frame at dt = 20 must run 3 steps, not 1.
  • Resetting the bank to zero after stepping. Up to dt of time is lost every frame and the world runs slow.
  • Testing bank > dt instead of bank >= dt. A bank of exactly dt must step.
  • Clamping the bank, or forgetting to clamp at all. The clamp applies to the elapsed time of the frame, before it is banked.

Your exercise

Implement the accumulator. The starter reads the script and prints one line per frame; you write the function that decides how many steps a frame buys and what is left in the bank. All times are whole milliseconds, so the arithmetic is exact. The most likely mistake is losing the leftover time.

Further reading: Glenn Fiedler, "Fix Your Timestep"; Erin Catto's Box2D documentation on the simulation loop.

Up next2D VectorsMath & Integration

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…