How to Debug Matter.js Sleeping Body Wake-Ups

Debugging erratic sleeping body wake-ups in Matter.js requires identifying the unexpected forces, micro-collisions, or threshold settings that cause inactive physics bodies to reactivate prematurely. This guide covers how to enable built-in visual debug options, apply dynamic color coding to highlight state transitions, render velocity vectors to detect micro-jitter, and monitor collision events to isolate the root cause of erratic wake-ups.

Enable Built-In Sleeping Render Options

Matter.js includes a default rendering flag specifically for visual debugging. When using the default Matter.Render module, you can visualize the sleeping state of bodies automatically by configuring render options:

const render = Matter.Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        wireframes: false,
        showSleeping: true // Dims sleeping bodies automatically
    }
});

When showSleeping is set to true, the default renderer lowers the opacity of resting bodies. If a body suddenly regains full opacity, it has woken up.

Dynamically Color-Code Sleep State Transitions

The default visual cue can be subtle. To make wake-ups immediately obvious, hook into the sleepStart and sleepEnd events on the Matter.Events dispatcher and alter the body's render fill style.

Matter.Events.on(engine, 'sleepStart', (event) => {
    event.source.bodies.forEach(body => {
        if (body.isSleeping) {
            body.render.fillStyle = '#4a90e2'; // Blue indicates sleeping
        }
    });
});

Matter.Events.on(engine, 'sleepEnd', (event) => {
    const body = event.source;
    body.render.fillStyle = '#e74c3c'; // Bright red indicates a wake-up
    console.log(`Body ${body.id} woke up at speed: ${body.speed}`);
});

Brightly coloring bodies the exact moment they wake up lets you quickly spot which body in a stack or pile triggers the chain reaction.

Trace Contact Points and Collision Events

Erratic wake-ups are often triggered by ghost collisions or continuous micro-contacts from adjacent resting bodies. You can visualize these contact points using Matter.js render flags:

render.options.showBroadphase = true;
render.options.showCollisions = true;
render.options.showSeparations = true;

To pinpoint the exact pair triggering a wake-up, listen to the collisionStart and collisionActive events:

Matter.Events.on(engine, 'collisionStart', (event) => {
    event.pairs.forEach(pair => {
        const { bodyA, bodyB } = pair;
        if (bodyA.isSleeping || bodyB.isSleeping) {
            console.warn(`Collision woke sleeping body: Body ${bodyA.id} <-> Body ${bodyB.id}`);
        }
    });
});

Visualize Micro-Velocities

Bodies often fail to stay asleep because tiny residual velocities continually reset the sleep timer. You can draw velocity vectors directly onto your canvas during the afterRender event to see if resting bodies are experiencing micro-jitter:

Matter.Events.on(render, 'afterRender', () => {
    const context = render.context;
    
    engine.world.bodies.forEach(body => {
        if (!body.isStatic) {
            context.beginPath();
            context.moveTo(body.position.x, body.position.y);
            // Scale velocity vector for visibility
            context.lineTo(
                body.position.x + body.velocity.x * 10,
                body.position.y + body.velocity.y * 10
            );
            context.strokeStyle = body.isSleeping ? '#2ecc71' : '#f39c12';
            context.lineWidth = 2;
            context.stroke();
        }
    });
});

Adjust Sleep Thresholds

If bodies wake up due to unavoidable simulation noise, tune the sleep sensitivity: