Changing Body Mass in Matter.js: Impact on Density

In Matter.js, changing a rigid body's mass directly alters its density, provided you use the official engine methods. Because Matter.js calculates density as mass divided by surface area, altering the mass while the body's geometry remains constant causes the engine to recalculate and update the body.density property automatically. However, how this update occurs depends strictly on whether you modify the body via the API or through direct property assignment.

The Relationship Between Mass, Density, and Area

Matter.js relies on a simple geometric formula to maintain physical consistency:

\[\text{density} = \frac{\text{mass}}{\text{area}}\]

When a body is initially created, Matter.js assigns a default density (typically 0.001) and calculates the initial mass based on the computed area of the shape.

Updating Mass Using Body.setMass

To safely update a body's mass, you should always use the built-in module function:

Matter.Body.setMass(body, newMass);

When you call Body.setMass(), Matter.js executes an internal routine that updates several dependent properties at once:

  1. Recalculates Density: The engine sets body.density = body.mass / body.area. Increasing mass increases density proportionally; decreasing mass lowers density.
  2. Updates Inverse Mass: It recalculates body.inverseMass = 1 / body.mass, which the collision solver relies on for performance.
  3. Adjusts Inertia: It scales the rotational inertia (body.inertia and body.inverseInertia) to match the new mass, preventing unnatural spinning or resistance during collisions.

Direct Mutation Pitfall (body.mass = value)

If you manually overwrite the property directly using body.mass = newMass, density will not change.

Matter.js does not use active getters and setters for its core physics properties. Directly assigning a new value to body.mass leaves body.density, body.inverseMass, and body.inertia at their previous values. This desynchronization can produce erratic physics behaviors, such as incorrect impulse responses during collisions and unnatural rotational dynamics.

Modifying Density Instead

If your goal is to make an object behave as if it were made of a heavier material (like changing wood to metal), the recommended approach in Matter.js is to alter the density directly rather than the mass:

Matter.Body.setDensity(body, newDensity);

Calling Body.setDensity() performs the inverse operation: it recalculates body.mass as density * area and updates all related inertia parameters accordingly.