How Matter.js Handles 2D Physics Simulation

Matter.js is an open-source 2D physics engine built for the web using JavaScript. It powers browser games and interactive visualizations by simulating realistic mechanical behaviors such as gravity, collisions, and friction. This article examines how Matter.js functions under the hood, exploring its core architecture, rigid body dynamics, two-phase collision detection system, constraint solving, and simulation loop execution.

The Modular Architecture

Matter.js relies on a decoupled, modular architecture where computation and rendering are separated:

Rigid Body Dynamics

Matter.js simulates rigid bodies—objects that do not deform when forces are applied. Bodies can be standard primitives (rectangles, circles) or arbitrary convex polygons.

Each body is defined by mechanical properties:

Collision Detection Pipeline

Matter.js uses a two-phase collision detection pipeline to maintain high performance when handling hundreds of moving bodies:

  1. Broadphase: The engine first performs an inexpensive pass using Axis-Aligned Bounding Boxes (AABB). By comparing the outer boundaries of objects, it quickly discards pairs that are too far apart to touch, producing a list of potential collision pairs.
  2. Narrowphase: For pairs that pass the broadphase, Matter.js executes the Separating Axis Theorem (SAT). SAT tests if a line (axis) can be drawn between two convex shapes where their projections do not overlap. If no separating axis exists, a collision is confirmed, and the engine calculates the penetration depth, collision normal, and contact points.

Collision Resolution and Constraint Solving

Once contacts are determined, the engine resolves overlaps to prevent objects from clipping through one another. Matter.js applies impulse-based dynamics:

Matter.js also includes a constraint solver used for joints, springs, and ropes. Constraints connect two bodies (or one body to a fixed point in space) and enforce distance limits. The solver iteratively adjusts the positions and velocities of constrained bodies across multiple solver iterations per frame to achieve stability and minimize drift.

The Simulation Loop

Every tick of the simulation advances the physical world by a discrete time step (delta). The Engine.update cycle executes the following sequence:

  1. Apply global forces (e.g., gravity) and custom external forces to all bodies.
  2. Update spatial structures and run the broadphase collision detection.
  3. Execute the narrowphase collision detection via SAT to generate contact manifolds.
  4. Solve active constraints iteratively.
  5. Solve collision impulses and adjust velocities.
  6. Integrate velocities to update body positions and rotations.
  7. Clear applied forces and dispatch collision events (collisionStart, collisionActive, collisionEnd).