Matter.js Extreme Mass Ratio Collision Instability

When simulating physics in Matter.js, pairing bodies with drastically disparate masses—such as a mass of 1 interacting with a mass of 10,000—frequently triggers severe physics artifacts, including jittering, tunneling, and explosive velocity spikes. This article breaks down the technical reasons why extreme mass ratios break the stability of the Matter.js iterative constraint solver, covering impulse distribution, position correction overshoot, and floating-point limitations, along with concrete methods to prevent these issues.

The Sequential Impulse Solver

Matter.js relies on an iterative sequential impulse solver to resolve collisions and constraints. When two bodies intersect, the engine calculates an impulse along the contact normal to prevent penetration and simulate restitution and friction.

The impulse magnitude \(J\) is inversely proportional to the sum of the inverse masses of the colliding bodies:

\[\text{Effective Mass} = \frac{1}{\frac{1}{m_A} + \frac{1}{m_B}}\]

When the mass of body \(B\) (\(m_B\)) is orders of magnitude larger than body \(A\) (\(m_A\)), \(1/m_B\) approaches zero. As a result, the effective mass is dictated almost entirely by the lighter body (\(m_A\)). While mathematically this represents an immovable object relative to the light body, the engine's discrete-time numerical integration turns this theoretical model into an unstable feedback loop.

Key Causes of Instability

1. Velocity Overshoot and Energy Injection

Because dynamic bodies are resolved incrementally across frames, an extremely heavy dynamic object barely slows down during an impact. In contrast, the lighter body receives nearly the entirety of the calculated velocity change. If the heavier body penetrates even slightly into the lighter body during a single time step, the impulse generated to halt penetration can accelerate the lighter object to an extreme speed in a single frame. This sudden injection of kinetic energy makes the simulation appear explosive.

2. Failure of Iterative Convergence

Matter.js does not solve all collision constraints simultaneously with a global matrix; it iterates through contact pairs sequentially. By default, the engine uses:

When mass ratios are moderate (e.g., 1:1 to 1:10), these iterations are sufficient to settle the contact forces smoothly. With extreme mass ratios, the solver cannot reach equilibrium within 4 to 6 passes. The lighter body bounces violently between the heavy body and any adjacent surfaces (such as the floor) within a single frame, resulting in rapid micro-collisions that destabilize the solver state.

3. Position Correction (Baumgarte Stabilization) Overshoot

Matter.js uses position correction to push overlapping bodies apart and counteract numerical drift. When two bodies overlap, the lighter body is forced to absorb almost 100% of the positional shift. Because the overlap resolution is applied abruptly to avoid sinking, the lighter body is displaced drastically over one step, frequently teleporting it inside neighboring geometry or far away from the contact point.

4. Floating-Point Precision Loss

Calculations involving large disparities in magnitude lead to rounding errors. Adding tiny inverse mass values to comparatively large numbers reduces the precision of normal and tangent vectors. In tight stacking scenarios or high-speed collisions, these precision deficits cause erratic normal calculations, manifesting as random lateral slides or perpetual jittering.

Solutions to Stabilize Collisions