How Position Iterations Affect Matter.js Stacking
In Matter.js, the accuracy of rigid-body simulations depends heavily
on the constraint solver's iterative passes. This article examines how
limiting the engine's positionIterations setting degrades
the stability of vertically stacked blocks, detailing the mechanical
causes of block penetration, jitter, and collapse, as well as the
practical trade-offs between simulation performance and structural
fidelity.
Understanding Position Iterations in Matter.js
Matter.js uses an iterative impulse-based solver to handle collisions and constraints. In every simulation step, the engine performs two primary solver loops: velocity iterations and position iterations.
Velocity iterations calculate and apply the impulses needed to stop
or bounce colliding bodies. Position iterations, on the other hand,
correct body overlaps (penetrations). Because floating-point rounding
errors and multi-body forces cause overlapping contacts, the position
solver shifts bodies apart over multiple passes until they either rest
cleanly on surface boundaries or hit the iteration limit defined by
engine.positionIterations.
The Consequences of Limiting Position Iterations on Stacks
When blocks are stacked vertically, the normal force compounds downward. The bottom block must support the combined weight of every block resting above it. Limiting position iterations directly impacts this scenario in several distinct ways:
- Unresolved Penetration (Block Sinking): With fewer iterations, the engine terminates the correction loop before eliminating overlap between stacked layers. Blocks appear to sink into one another, with the deepest penetration occurring at the bottom of the stack where forces are highest.
- Artificial Elasticity and "Sponginess": Because penetrations are only partially resolved in each tick, the stack loses its rigid quality. Instead of behaving like solid stone or wood, the column behaves like a stack of dense sponges, compressing under downward pressure and rebounding erratically.
- Persistent Jitter and Micro-Bouncing: When the position solver fails to find a stable equilibrium, overlapping bodies continuously receive small corrective nudges on alternating frames. This manifests visually as high-frequency vibration or jittering across the block faces.
- Horizontal Drift and Premature Collapse: Unresolved vertical overlap frequently creates asymmetric corrective vectors. Even a minuscule horizontal push resulting from an imperfect contact point will cause a column of blocks to slide sideways, tilt, and topple without any external lateral force.
The Trade-off: Stability vs. Performance
The default positionIterations value in Matter.js is
typically set to 6. Lowering this value (e.g., to 1 or 2) cuts CPU
overhead, enabling smoother frame rates on low-powered devices or in
scenes with hundreds of moving objects.
However, tall vertical stacks represent one of the most demanding configurations for an iterative solver. For reliable stacks exceeding four or five blocks:
- Reducing position iterations guarantees rapid failure of the stack.
- Stabilizing tall structures generally requires increasing
engine.positionIterationsto values between 8 and 16, often alongside an increase inengine.velocityIterations. - If performance constraints make higher iterations unviable, stability must instead be achieved by widening block bases, lowering the height of the stacks, or using compound bodies and explicit constraints rather than relying solely on surface friction and resting contact.