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:
- Increase
sleepThreshold: The default is 60 updates. Increasingbody.sleepThresholdrequires the body to remain below the motion limit longer before sleeping, reducing flip-flop behavior. - Adjust Motion Calculations: A body wakes up when
body.motion > 0.1. You can clamp residual velocity manually in abeforeUpdatehook to force stationary objects to reach the resting threshold.