How to Simulate Vehicle Suspension in Matter.js

Simulating a four-wheeled vehicle suspension in Matter.js involves modeling the chassis and wheels as independent rigid bodies connected by elastic constraints. By tuning constraint properties such as stiffness, damping, and rest length, you can create responsive springs and shock absorbers that absorb terrain impacts while maintaining vehicle stability. This guide covers how to set up the vehicle geometry, isolate collisions using collision filters, configure realistic spring-damper constraints, and restrict wheel motion to a linear vertical axis.

1. Create the Chassis and Wheels

Start by defining a rectangular body for the vehicle chassis and circular bodies for the wheels. Because Matter.js operates in a 2D plane, a four-wheeled vehicle is typically represented from a side profile using two visible wheel assemblies (front and rear), though you can adjust the mass and spring stiffness to reflect the weight distribution of four wheels.

const { Engine, Render, Runner, Bodies, Composite, Constraint } = Matter;

// Create chassis
const chassis = Bodies.rectangle(400, 300, 200, 40, {
  mass: 10,
  collisionFilter: { group: -1 } // Prevent chassis from colliding with its wheels
});

// Create wheels
const wheelRadius = 25;
const rearWheel = Bodies.circle(330, 340, wheelRadius, {
  friction: 0.8,
  mass: 2,
  collisionFilter: { group: -1 }
});

const frontWheel = Bodies.circle(470, 340, wheelRadius, {
  friction: 0.8,
  mass: 2,
  collisionFilter: { group: -1 }
});

Using a negative group value inside collisionFilter guarantees that the chassis and wheels pass through each other without registering unwanted internal collisions, while still interacting normally with terrain and obstacles.

2. Configure Spring and Damper Constraints

In Matter.js, the Constraint module provides the mechanics for both the suspension spring and the shock absorber through the stiffness and damping properties:

// Rear suspension constraint
const rearSuspension = Constraint.create({
  bodyA: chassis,
  pointA: { x: -70, y: 20 },
  bodyB: rearWheel,
  pointB: { x: 0, y: 0 },
  stiffness: 0.15,
  damping: 0.1,
  length: 40
});

// Front suspension constraint
const frontSuspension = Constraint.create({
  bodyA: chassis,
  pointA: { x: 70, y: 20 },
  bodyB: frontWheel,
  pointB: { x: 0, y: 0 },
  stiffness: 0.15,
  damping: 0.1,
  length: 40
});

3. Restrict Lateral Wheel Movement

A single constraint acts as a free-swinging pendulum, causing wheels to swing forward and backward instead of strictly compressing upward into the vehicle body. To replicate a real automotive strut, lateral deflection must be constrained.

The most effective method in 2D is using a dual-constraint triangle or adding a secondary horizontal limiter constraint:

// Secondary constraint to restrict horizontal displacement for the rear wheel
const rearAxisGuide = Constraint.create({
  bodyA: chassis,
  pointA: { x: -70, y: -20 },
  bodyB: rearWheel,
  pointB: { x: 0, y: 0 },
  stiffness: 0.15,
  damping: 0.1,
  length: 65 // Hypotenuse distance from upper chassis point to wheel
});

// Secondary constraint for the front wheel
const frontAxisGuide = Constraint.create({
  bodyA: chassis,
  pointA: { x: 70, y: -20 },
  bodyB: frontWheel,
  pointB: { x: 0, y: 0 },
  stiffness: 0.15,
  damping: 0.1,
  length: 65
});

Triangulating each wheel with two constraints sharing identical stiffness and damping properties keeps the wheel traveling along a stable vertical track relative to the vehicle body.

4. Assemble and Tune the Vehicle

Group the bodies and constraints into a single Matter.js composite and add them to the world simulation:

const car = Composite.create();
Composite.add(car, [
  chassis,
  rearWheel,
  frontWheel,
  rearSuspension,
  frontSuspension,
  rearAxisGuide,
  frontAxisGuide
]);

Composite.add(world, car);

When tuning the vehicle: