Understanding the Matter.js beforeUpdate Event

This article provides an overview of the beforeUpdate event in Matter.js, a 2D physics engine for the web. You will learn what the event is, where it sits within the physics simulation loop, why and when you should use it, and how to implement it using clear code examples.

What is the beforeUpdate Event?

In Matter.js, the beforeUpdate event is emitted by the Engine immediately before it updates the simulation state. The physics engine operates on a recurring update loop where it calculates forces, updates positions, resolves constraints, and detects collisions. Listening to beforeUpdate allows you to execute custom code on every tick right before those calculations occur.

Position in the Engine Lifecycle

To understand beforeUpdate, it helps to see the standard sequence of events inside the Matter.Engine.update cycle:

  1. beforeUpdate: Triggered before any physics math or integration takes place.
  2. Collision & Force Integration: The engine calculates gravity, velocities, body positions, and collision pairs.
  3. afterUpdate: Triggered immediately after all physics calculations for the tick are finalized.

Because beforeUpdate runs prior to position updates and collision resolution, any modifications made to bodies during this event will be factored into the immediate frame's calculations.

Common Use Cases

The beforeUpdate hook is ideal for logic that directly influences the physics step:

Implementation Example

You attach a listener to the beforeUpdate event using the Matter.Events.on() method:

const { Engine, Events, Body, Vector } = Matter;

// Create an engine instance
const engine = Engine.create();

// Listen to the beforeUpdate event
Events.on(engine, 'beforeUpdate', function(event) {
    // Current simulation timestamp
    const timestamp = event.timestamp;

    // Example: Apply an upward force (anti-gravity) to a specific body
    Body.applyForce(playerBody, playerBody.position, {
        x: 0,
        y: -0.05
    });

    // Example: Clamp body velocity to prevent tunneling
    const maxSpeed = 10;
    if (Vector.magnitude(playerBody.velocity) > maxSpeed) {
        Body.setVelocity(playerBody, Vector.mult(Vector.normalise(playerBody.velocity), maxSpeed));
    }
});

beforeUpdate vs. afterUpdate