What Evicts Collision Pairs in Matter.js Pairs Table

In Matter.js, collision pairs are evicted from the Matter.Pairs table when two previously colliding bodies separate, when one or both bodies are removed from the physics world, or when bodies transition into a sleeping state. During each engine update, Matter.Pairs.update validates active contacts against the narrowphase collision detector; any tracked pair that fails to register a collision in the current frame is marked inactive, triggers a collisionEnd event, and is purged from internal storage to conserve memory and maintain accurate collision tracking.

The Role of the Pairs Table

The Matter.Pairs module maintains a cache of active collisions between rigid bodies. Each collision pair is assigned a unique identifier string (derived from the two body IDs, such as A1_B2) and stored in a lookup dictionary named pairs.table, as well as an array called pairs.list.

This table allows the engine to preserve contact data across ticks, warm-start collision impulses for stability, and determine whether a collision is beginning, persisting, or terminating.

Primary Eviction Triggers

1. Physical Separation (Narrowphase Non-Detection)

The most common trigger is the physical separation of two bodies.

  1. During the broadphase, the engine finds potential bounding-box overlaps.
  2. During the narrowphase (Separating Axis Theorem), the engine calculates exact intersection manifolds.
  3. For every confirmed collision, pair.timeUpdated is set to the current engine tick timestamp.
  4. If two bodies drift apart, the narrowphase generates no collision for that pair.
  5. In Pairs.update, the engine scans existing pairs: if a pair’s timeUpdated does not match the current engine timestamp, the engine recognizes that the bodies are no longer touching.

2. Body Removal or World Despawn

When an entity is removed from a Composite or World via Composite.remove(world, body), the body no longer exists in the collision pipeline. Because the broadphase skips the removed body, no new collision can be recorded in subsequent ticks. Consequently, any active pair referencing the deleted body fails the timestamp validation check during the next Pairs.update pass and is cleared.

3. Body Sleeping Transitions

When Matter.js sleep mode is enabled, bodies that drop below predefined velocity and motion thresholds enter a sleep state. While the engine retains contact constraints for sleeping bodies resting on each other, moving bodies that separate from a settling or sleeping body stop generating active collision manifold updates. Once the interaction ceases, the unrefreshed pair is evicted.

The Eviction Lifecycle in Pairs.update

When an eviction is triggered, the engine executes the cleanup systematically:

  1. Stale Identification: The engine iterates backward through pairs.list and compares each pair.timeUpdated to the current timestamp.
  2. State Transition: If the timestamps do not match, Pair.setActive(pair, false, timestamp) flags the collision as inactive.
  3. Event Generation: The inactive pair is queued into the engine's internal collisionEnd event array, notifying listeners that the contact has ceased.
  4. Table Deletion: The engine removes the pair’s reference from the pairs.table hash map using delete pairs.table[pair.id].
  5. List Splice: The pair is spliced out of pairs.list, freeing memory references and ensuring subsequent solver iterations skip the pair entirely.