Reduce Matter.js Iterations on Low-Power Devices
Simulating rigid-body physics on resource-constrained mobile hardware
requires balancing performance and simulation stability. In Matter.js,
lowering engine.positionIterations drastically reduces CPU
consumption and thermal throttling, but it frequently introduces stack
instability, resulting in jitter, body penetration, and collapsing
structures. This article outlines practical architectural adjustments,
engine parameters, and physics design choices to safely decrease
position iterations without compromising the integrity of stacked
objects.
1. Normalize Mass Ratios in Stacks
Physics solvers struggle to resolve contacts between bodies with vastly differing masses using low iteration counts. When a heavy body sits on a lighter one, low position iterations cause the heavier object to penetrate the lower object, producing spring-like jitter.
- Ensure stacked bodies have uniform or gradually tapering masses.
- Avoid placing objects with high mass density atop low-density objects.
- Clamp
body.densityvalues across stackable elements to maintain a 1:1 or near 1:1 mass ratio.
2. Tune Collision Slop and Restitution
The slop property dictates the depth by which bodies can
penetrate before position corrections trigger. Increasing this value
prevents the solver from violently over-correcting slight overlaps at
low iteration counts.
- Increase
Matter.Resolver._restingThreshto suppress micro-bounces within stacks. - Set the
restitution(bounciness) of all stack elements to0. Any elastic response rapidly destabilizes stacks when positional solver cycles are limited. - Adjust
body.slopfrom its default (typically0.05) upward slightly (e.g.,0.1to0.2) to provide the solver a wider tolerance window before applying corrective impulses.
3. Aggressively Enable Body Sleeping
The most effective way to run low iterations without stack collapse is to remove resting stacks from the simulation loop altogether.
- Set
enableSleeping: trueon theMatter.Engineconfiguration. - Lower the sleep threshold by decreasing
Matter.Sleeping._motionSleepThresholdto force stacked bodies to enter a sleeping state sooner. - Once stacked bodies sleep, their positions lock until an external dynamic impulse awakens them, eliminating idle computational overhead and drift.
4. Adjust the Balance Between Solver Passes
Matter.js decouples constraint calculations into
positionIterations and velocityIterations.
While position iterations correct overlap, velocity iterations resolve
kinetic impulses.
- Reduce
positionIterations(e.g., from6down to2or3). - Keep
velocityIterationsslightly higher (e.g.,4or5). - Resolving velocities accurately prevents bodies from building up phantom kinetic energy between frames, which naturally keeps stacks aligned even when position corrections are low.
5. Utilize Chamfered Geometry
Sharp 90-degree corners on stacked boxes cause erratic contact normals when objects overlap under low solver precision.
- Apply rounded corners to rectangular bodies using the
chamferoption:Bodies.rectangle(x, y, w, h, { chamfer: { radius: 2 } }). - Chamfering smooths contact manifold transitions, allowing faces to slide into resting equilibrium rather than catching on vertex boundaries.
6. Clamp Variable Delta Time
Mobile web environments frequently experience frame drops, leading to
large, unpredictable time-step deltas (dt). When
dt spikes, a low-iteration solver fails completely, causing
stacks to explode.
- Enforce a fixed time step inside your game loop (e.g.,
16.66msfor 60 FPS). - Clamp the maximum allowable delta inside the
Engine.update(engine, delta)call to prevent the physics engine from attempting to resolve large positional displacements in a single step.