What Happens Without Runner.run in Matter.js
In Matter.js, the Runner module provides the execution
loop responsible for continuously updating the physics simulation over
time. If you do not call Runner.run(runner, engine), the
physics engine will remain completely dormant, meaning bodies will not
move, gravity will not take effect, and collisions will not resolve.
This article explains the mechanics of the Runner, what
happens to your scene when it is omitted, and how you can manually drive
the simulation if you choose not to use it.
The Physics Engine Remains Frozen
The core Matter.Engine does not run on an internal timer
by default; it is purely a state machine that calculates physics steps
on demand. Calling Runner.run() establishes a recurring
loop using requestAnimationFrame (in the browser) to
continuously step the engine forward in time.
If you do not call this method:
- No Time Progression: The simulation time does not advance.
- Static Entities: Rigid bodies added to the
Compositeworld will remain frozen at their initial coordinates. - No Forces or Collisions: Gravity, applied forces, velocities, and collision detection routines will never execute.
- Silent Event Listeners: Engine-level events such as
beforeUpdate,afterUpdate,collisionStart, andcollisionActivewill never fire because the update cycle is never triggered.
What Happens to the Renderer?
If you are using the built-in Matter.Render module and
call Render.run(render), the canvas will still initialize
and draw your bodies. However, because the physics state never advances,
the renderer simply re-draws the exact same initial positions on every
frame. This often leads to confusion, making it appear as though gravity
is broken or rigid bodies are permanently static.
Manual Simulation Updates
Skipping Runner.run is not always a bug; developers
often do this intentionally when integrating Matter.js into existing
rendering engines like Three.js, PixiJS, or standard game loops.
If you omit Runner.run, you must manually advance the
engine using Engine.update() inside your own animation
loop:
function gameLoop(timestamp) {
// Manually advance the physics engine by 16.66ms (or use a calculated delta)
Matter.Engine.update(engine, 1000 / 60);
// Custom rendering or logic goes here
requestAnimationFrame(gameLoop);
}
requestAnimationFrame(gameLoop);Failing to provide either Runner.run or a manual call to
Engine.update ensures that your Matter.js physics world
will never execute.