Matter.Composite.allConstraints in Matter.js

This article explains how the Matter.Composite.allConstraints function works within Matter.js to recursively traverse nested scene graphs and extract every constraint. In physics simulations involving complex ragdolls, ropes, or mechanisms, bodies and joints are often nested within multiple sub-composites. Matter.Composite.allConstraints traverses this entire tree structure to flatten and return a single unified array containing every joint, spring, and pin.

The Composite Tree Hierarchy

In Matter.js, a Composite acts as a container capable of holding bodies, constraints, and other child composites. This architecture forms a directed tree structure where a top-level composite (such as the main engine.world) can contain intermediate composites representing individual multi-part objects, which in turn can contain their own sub-assemblies.

Because individual composite.constraints arrays only store constraints directly attached to that specific container level, accessing constraints scattered across a deeply nested hierarchy manually would require custom recursive iteration.

How the Traversal Works

When Matter.Composite.allConstraints(composite) is invoked, it follows a recursive collection algorithm:

  1. Local Collection: The function initializes an internal array and copies all constraints present in the target composite's immediate constraints list.
  2. Child Iteration: It inspects the composite.composites array to determine if any child composites exist.
  3. Recursive Aggregation: For each child composite found, the function recursively calls Matter.Composite.allConstraints on that child.
  4. Array Flattening: The results returned from child composites are concatenated into the parent collection.
  5. Return Flat List: Once the entire subtree is traversed, a single, flattened array containing references to all constraints across every branch is returned.

Practical Implications and Performance

Matter.Composite.allConstraints ensures that constraint solvers and debug renderers can access every active linkage in the simulation without needing prior knowledge of how deeply nested the objects are.

Because this function creates and concatenates new arrays at every level of the hierarchy during recursion, calling it repeatedly inside high-frequency update loops (such as beforeUpdate or the render loop) can trigger excessive garbage collection. For optimal performance in dynamic scenes, query the constraints once and maintain references, or only invoke allConstraints when the hierarchy is modified.