Reset Body Velocity and Forces in Matter.js

Object pooling is an effective performance optimization in Matter.js, but reusing physics bodies requires completely clearing residual movement and applied dynamics. This article outlines the essential steps to reset a Matter.js rigid body's linear velocity, angular velocity, applied forces, and internal motion properties so it can be reliably recycled without lingering physical behaviors from its previous lifecycle.

1. Reset Linear and Angular Velocities

Matter.js provides built-in methods on the Matter.Body module to adjust velocities. Setting these properties to zero prevents the body from carrying inertia into its next use:

Matter.Body.setVelocity(body, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(body, 0);

Using Matter.Body.setVelocity updates both the current velocity vector and internal speed calculations.

2. Clear Forces and Torque

Matter.js accumulates forces and torques across simulation steps. If a body was deactivated or returned to the pool while external forces were acting on it, these vectors must be explicitly cleared:

body.force = { x: 0, y: 0 };
body.torque = 0;

3. Update Position and Synchronize Previous State

Matter.js uses Verlet integration, which calculates velocity partly based on the difference between the current position (body.position) and the previous position (body.positionPrev).

If you reposition a pooled body using direct assignment rather than the API, the engine may infer a massive velocity spike during the next engine update. Always use Matter.Body.setPosition and Matter.Body.setAngle:

Matter.Body.setPosition(body, { x: newX, y: newY });
Matter.Body.setAngle(body, newAngle);

These functions automatically synchronize positionPrev and anglePrev with the new coordinates, eliminating accidental phantom velocities.

4. Wake Up Sleeping Bodies

If your world configuration utilizes sleep states (Matter.Sleeping), a pooled body may have entered a sleeping state. Re-enabling the body requires waking it:

Matter.Sleeping.set(body, false);

Complete Reset Function

Combine these steps into a single utility function within your object pool manager:

function resetPooledBody(body, x, y, angle = 0) {
    // 1. Reset dynamic motion
    Matter.Body.setVelocity(body, { x: 0, y: 0 });
    Matter.Body.setAngularVelocity(body, 0);

    // 2. Clear accumulated forces
    body.force = { x: 0, y: 0 };
    body.torque = 0;

    // 3. Update transform without velocity spikes
    Matter.Body.setPosition(body, { x: x, y: y });
    Matter.Body.setAngle(body, angle);

    // 4. Ensure the body is active in simulation
    Matter.Sleeping.set(body, false);
}

Calling this function immediately before re-adding the body to the active simulation guarantees predictable physics behavior.