How to Fix Floating Bodies in Matter.js

When a physics body unexpectedly floats in mid-air in Matter.js, the issue typically stems from misconfigured body properties, disabled engine gravity, sleep states, or visual-engine synchronization mismatches. This guide walks through the systematic steps required to identify why a body refuses to fall, covering gravity settings, collision misconfigurations, static flags, and debugging tools.

1. Enable Wireframe Debug Rendering

Visual representations often drift from their underlying physics bodies, or invisible static boundaries might be blocking movement. Switch Matter.js's built-in renderer to wireframe mode to inspect the actual colliders:

render.options.wireframes = true;
render.options.showPositions = true;
render.options.showVelocity = true;

This immediately reveals whether the body is genuinely floating or if it is resting on an invisible ground, border, or improperly positioned static fixture.

2. Check the isStatic Flag

A body marked as static ignores forces, collisions, and gravity:

console.log(myBody.isStatic);

If myBody.isStatic is true, set it to dynamic using the built-in method:

Matter.Body.setStatic(myBody, false);

3. Verify World Gravity Settings

If gravity has been disabled or set to zero on the engine, all dynamic bodies will remain stationary:

console.log(engine.gravity.y, engine.gravity.scale);

The default values are y = 1 and scale = 0.001. If scale or y is 0, restore them:

engine.gravity.y = 1;
engine.gravity.scale = 0.001;

4. Inspect frictionAir

The frictionAir property acts as air resistance. If it is set too high (for example, 1 or greater), the downward force of gravity will immediately be canceled out, making the object appear pinned in space:

console.log(myBody.frictionAir);

The default is 0.01. Reset it if it was changed:

myBody.frictionAir = 0.01;

5. Check the Sleeping State

Matter.js includes a sleep system to save performance on motionless objects. If enableSleeping: true is set on the engine, a body might enter sleep before moving:

console.log(myBody.isSleeping);

To wake the body programmatically:

Matter.Sleeping.set(myBody, false);

Alternatively, disable sleeping globally during testing:

engine.enableSleeping = false;

6. Verify Mass and Inertia

Setting a body's mass or density to Infinity causes it to behave like a static object:

console.log(myBody.mass, myBody.density);

Ensure the body has a valid, finite mass. If the mass was altered inadvertently, recalculate it via density:

Matter.Body.setDensity(myBody, 0.001);

7. Confirm the Engine Update Loop

If you are running a custom render loop instead of Matter.Runner, ensure Engine.update(engine, delta) is actually executing every frame. If the engine stops updating, all physics freeze while custom animations might still run:

function loop(time) {
  Matter.Engine.update(engine, 1000 / 60);
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);