Stabilize Stacks of Rigid Bodies in Matter.js
Stacking rigid bodies in Matter.js often leads to unwanted jittering, sliding, and sudden collapses due to iterative constraint solving limitations. This guide outlines the core engine configurations and body properties required to achieve a rock-solid, stable vertical stack in your Matter.js simulations.
Increase Constraint Iterations
By default, Matter.js prioritizes performance over precision, resolving constraints with relatively low solver iterations. Increasing these values forces the physics solver to perform more passes to correct overlaps and velocities, which dramatically reduces jitter in tall stacks.
const engine = Matter.Engine.create({
positionIterations: 10, // Default is 6
velocityIterations: 8 // Default is 4
});For exceptionally tall stacks, setting
positionIterations to 12 or higher will significantly
improve stability at the cost of some performance.
Use Fixed Time Steps and Sub-Stepping
Relying on variable frame rates creates inconsistent forces that destabilize stacks. Run your simulation with a fixed time step. To achieve the highest stability, run multiple smaller engine updates per animation frame (sub-stepping) instead of a single large update.
const fixedDelta = 1000 / 60; // 60 FPS
const subSteps = 2;
function tick() {
for (let i = 0; i < subSteps; i++) {
Matter.Engine.update(engine, fixedDelta / subSteps);
}
requestAnimationFrame(tick);
}Eliminate Restitution and Increase Friction
Elasticity causes energy to bounce through the stack, magnifying oscillations. When creating bodies for stacking:
- Restitution: Set to
0to prevent micro-bouncing between adjacent bodies. - Friction: Increase regular friction to around
0.5or higher to resist lateral sliding. - Static Friction: Increase
frictionStaticto1.0or higher to keep touching surfaces locked in place until a significant force moves them.
const box = Matter.Bodies.rectangle(x, y, width, height, {
restitution: 0,
friction: 0.8,
frictionStatic: 1.2
});Enable Body Sleeping
Matter.js includes a sleeping mechanism that stops simulating bodies that have come to rest. Once a stack settles, sleeping eliminates numerical drift and micro-jitters completely.
engine.enableSleeping = true;A sleeping body will remain entirely motionless until another active body collides with it.
Adjust Collision Slop
Every body has a slop property, which defines how much
overlap is tolerated before the collision solver forces them apart. If
the slop is too high, bodies will sink into each other; if too low, the
engine will aggressively push them apart, causing vibration.
The default slop is 0.05. For stacking, slightly
lowering it (e.g., 0.01 to 0.02) helps prevent
deep sinking without introducing excessive jitter.
Matter.Bodies.rectangle(x, y, width, height, {
slop: 0.02
});Manage Mass Distribution
A tall stack of identical masses transfers force unevenly down to the base. If possible, ensure that lower bodies are slightly heavier than upper bodies. Avoid placing large, heavy bodies directly on top of small, light bodies, as this creates extreme mass ratios that iterative solvers struggle to resolve cleanly.