How Matter.Pairs.update Preserves Contacts

In Matter.js, Matter.Pairs.update maintains the state of colliding rigid bodies across successive frames by caching, updating, and pruning contact pairs. Rather than reallocating collision records every frame, this method matches fresh collision detections against an internal hash table of existing pairs. This persistence mechanism enables accurate collision event lifecycles—such as distinguishing when collisions start, persist, or end—and allows the engine to preserve accumulated impulse data necessary for warm-starting the constraint solver and eliminating physical jitter.

Deterministic Pair Indexing

Contact persistence relies on consistent identification of interacting bodies. During the broadphase and narrowphase steps, collision detectors evaluate interactions between bodies. When a collision occurs between two objects, Matter.js derives a deterministic string identifier via Pair.id(bodyA, bodyB). This identifier orders body IDs canonically (ensuring that an interaction between Body A and Body B produces the same key regardless of argument order).

Matter.Pairs maintains a lookup table (pairs.table) indexed by these keys. During Pairs.update, incoming collisions are checked against pairs.table to determine whether the contact is newly formed or already established.

In-Place State Mutation

When a collision matches an existing entry in pairs.table:

  1. Object Retention: The engine does not instantiate a new Pair object. It updates the existing reference with new geometric data, including the collision normal, penetration depth, and contact points calculated by the Separating Axis Theorem (SAT).
  2. Lifecycle Flagging: The pair's isActive flag is maintained, and internal timestamps (timeUpdated) are refreshed to match the current engine tick. This avoids the garbage collection overhead associated with allocating new objects on every physics step.
  3. Event Classification: By comparing the current active pairs with those from the previous frame, the system determines which contacts trigger collisionStart, which continue as collisionActive, and which are removed to fire collisionEnd.

Impulse Preservation and Warm Starting

Preserving contact pairs across frames is critical for physical stability. The iterative constraint solver in Matter.js resolves resting contacts, stacking, and friction by accumulating impulses over multiple iterations.

Because Pairs.update mutates existing pair references instead of replacing them, the engine retains previously calculated normal and tangential impulses. The constraint solver utilizes these stored values as an initial guess for the next frame—a technique known as warm starting. Warm starting significantly improves convergence rates, prevents bodies from sinking into one another, and stops resting stacks from jittering.

Pruning Inactive Contacts

To ensure memory does not leak and non-colliding bodies do not retain phantom contacts, Matter.Pairs.update tracks pair validity: