Ammo.js stepSimulation Sequence of Events

When developing 3D applications with ammo.js (the Emscripten port of the Bullet Physics library), the stepSimulation method is the core driver of the physics world. This article breaks down the exact sequence of internal events and phases that occur during a single call to stepSimulation, including time integration, collision detection, constraint solving, and interpolation.

When you call dynamicsWorld.stepSimulation(timeStep, maxSubSteps, fixedTimeStep), the engine executes the following precise sequence of events:

1. Sub-step Calculation and Time Accumulation

Ammo.js does not simulate physics using variable frame rates, as this would cause unstable and non-deterministic behavior. Instead, it uses a fixed time step. * Accumulate Time: The engine adds the passed timeStep (usually the time elapsed since the last render frame) to an internal time accumulator. * Determine Sub-steps: The engine calculates how many fixed steps of size fixedTimeStep (default is 1/60th of a second) are required to match the accumulated time. * Clamp Steps: If the required number of steps exceeds maxSubSteps, the engine clamps the simulation to prevent the “spiral of death” (where physics lag slows down rendering, causing even more physics steps to be queued).

2. The Internal Single-Step Loop

For each calculated sub-step, ammo.js executes a single, self-contained simulation step. If the accumulated time is too small for a single sub-step, this loop is skipped, and the engine jumps straight to the interpolation phase. Within each individual sub-step, the following sequence occurs:

3. State Interpolation

Once the sub-step loop completes, there is almost always a small remainder of time left in the accumulator that was not enough to trigger another full fixed step.

To prevent visual stuttering, ammo.js calculates an interpolation factor between 0 and 1 based on this remaining time. It then interpolates the positions and orientations of the rigid bodies between the previous physics state and the current physics state. This interpolated transform is what is exposed to your graphics renderer, ensuring smooth motion even when the rendering frame rate does not align perfectly with the physics simulation rate.