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:
friction: The kinetic (dynamic) friction applied to a body while it is actively sliding across another surface.frictionStatic: The resistance applied when a body is stationary relative to the surface it touches.
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:
- 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
frictionStaticvalue absorbs these small impulses, preventing resting bodies from slowly drifting, sliding apart, or collapsing prematurely. - 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
frictionStaticis 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.
Recommended Values and Common Issues
- Default Value: Matter.js defaults
frictionStaticto0.5(paired with a default dynamicfrictionof0.1). - Zero Static Friction (
0.0): Setting this property to zero removes the static threshold. Even infinitesimal forces will cause resting bodies to slip immediately. - High Static Friction (
> 1.0or higher): Useful for sticky surfaces, high-traction tires, or stacks of items that must withstand heavy impacts before shifting. - Creep or "Jittering": If resting stacks creep
across the floor, increasing
frictionStaticalongside engine iterations (e.g., increasingengine.positionIterationsandengine.velocityIterations) provides the necessary constraint enforcement to keep resting objects completely still.