Matter.js frictionStatic and Resting Bodies

In the Matter.js 2D physics engine, frictionStatic defines the threshold force required to initiate movement between two surfaces currently at rest relative to each other. This article explains the fundamental role of frictionStatic, how the engine computes resistance between resting bodies, its effects on stacking and inclined planes, and how to calibrate it to maintain stable physics simulations.

The Role of Static Friction in Matter.js

Static friction represents the physical resistance that must be overcome to transition an object from a state of rest into motion. Matter.js separates friction into two primary properties:

When two bodies touch without relative lateral velocity, frictionStatic dictates how much tangential force (shear force) can be applied before the bodies begin to slip. Until this threshold is crossed, the engine applies an opposing force that keeps relative velocity at zero. Once the tangential force exceeds the static limit, the contact breaks, and the engine switches to using standard dynamic friction.

Behavior on Resting and Stacked Bodies

When bodies are resting on each other, frictionStatic serves two crucial purposes:

  1. Stack Stability: In vertical or offset stacks (such as a tower of blocks), minor external perturbations, solver rounding errors, or micro-vibrations can impart small lateral forces. A sufficient frictionStatic value absorbs these small impulses, preventing resting bodies from slowly drifting, sliding apart, or collapsing prematurely.
  2. Holding Angles on Inclines: When an object rests on an inclined surface, gravity decomposes into a normal force pressing into the surface and a shear force pulling the body down the slope. The object remains stationary only if the static friction limit exceeds the shear force. If frictionStatic is too low, the object immediately begins sliding, even on very gentle gradients.

How Matter.js Calculates Static Friction

When two bodies collide or rest against one another, Matter.js resolves contact pairs by determining a single combined friction coefficient. By default, the engine determines the effective static friction by evaluating both contacting surfaces:

// Effective static friction is determined by the higher static friction value
effectiveFrictionStatic = Math.max(bodyA.frictionStatic, bodyB.frictionStatic);

Because it uses Math.max(), an object with a high frictionStatic can maintain grip on a surface that has a lower static friction value.

The maximum allowable shear force before slippage occurs is proportional to the normal force holding the bodies together:

\[\text{Maximum Static Friction Force} = \text{effectiveFrictionStatic} \times \text{Normal Force}\]

If external forces (gravity, user drag, or impulses) do not exceed this threshold, Matter.js cancels out the tangential velocity completely for that step.