Skip to content
Lesson 11 of 14

Step 1 of 5 · Reading · ~1 min

Read

Resources & Rendering

Physics Integration

Once you have velocities, you need to advance positions over time. The simplest integrator is explicit Euler:

x += v * dt
v += a * dt

Quick to type — and quick to blow up. Energy creeps in every step. A pendulum simulated with explicit Euler swings wider every cycle until it flies off into space.

Semi-implicit (symplectic) Euler

Reverse the order:

v += a * dt    # update velocity first
x += v * dt    # then use the NEW velocity to advance position

This tiny change makes the integrator symplectic: it preserves a discrete energy quantity. Pendulums oscillate at near-constant amplitude. Bouncing balls don't gain or lose energy by themselves. This is what Bullet, Box2D, and most game engines actually use.

Why a fixed dt matters

If dt varies per frame (because rendering speed varies), the simulation is no longer reproducible. Two clients running the same inputs will drift. So engines decouple:

  • Rendering runs at the variable display rate.
  • Physics ticks at a fixed dt (60 or 120 Hz typical).
  • An accumulator (from the earlier lesson) bridges the two.

Lockstep multiplayer (RTS, fighting games) and deterministic replays rely entirely on a fixed-dt simulation.

Higher-order integrators

For higher accuracy:

  • Verlet (position-based, no explicit velocity) — used in cloth, hair, particle systems.
  • RK4 — 4 force samples per step; very accurate; rarely used in games because it's 4x the cost.
  • Constraint solvers (Gauss-Seidel, PGS) — Box2D and Bullet iterate to satisfy constraints (joints, contacts) per step.

The Practice problem

You'll implement semi-implicit Euler exactly. Constant gravity, multiple bodies, step the simulation n times, dump positions. The same loop, scaled up with constraints, is the heart of a 2D physics engine.

Up nextScripting & GameplayProduction

Discussion

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

Sign in to post a comment or reply.

Loading…