Build a Rope in Matter.js Using Chain Composite

This article explains how to create a realistic physics-based rope in Matter.js using the Composites.chain utility. You will learn how to generate a series of connected rigid bodies with Composites.stack, link them sequentially using Composites.chain, anchor the structure to a fixed point in the scene, and adjust constraint properties for optimal rope behavior.

1. The Core Concept

In Matter.js, a rope is not a single deformable object; it is simulated as a series of small, rigid bodies connected by distance constraints. The Matter.Composites.chain function simplifies this process by automatically creating distance constraints between adjacent bodies in a composite group.

2. Implementation Steps

Step 1: Initialize Aliases

First, import the required Matter.js modules:

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

Step 2: Create Rope Segments with Composites.stack

Use Composites.stack to generate a linear column or row of small rectangles or circles that serve as the links of your rope:

const group = Matter.Body.nextGroup(true); // Prevents segments from colliding with each other

const ropeSegments = Composites.stack(200, 50, 1, 10, 0, 10, function(x, y) {
    return Bodies.rectangle(x, y, 10, 20, {
        collisionFilter: { group: group },
        chamfer: 5 // Optional: rounds edges for smoother movement
    });
});

Step 3: Connect Segments with Composites.chain

Call Composites.chain to link each segment to the next:

Composites.chain(ropeSegments, 0.5, 0.5, -0.5, -0.5, {
    stiffness: 0.8,
    damping: 0.1,
    render: {
        visible: true,
        lineWidth: 2
    }
});

Step 4: Anchor the Rope to a Fixed Point

To prevent the rope from falling completely under gravity, attach the top segment to a static point in space:

const anchor = Constraint.create({
    pointA: { x: 205, y: 50 }, // World coordinates where the rope hangs
    bodyB: ropeSegments.bodies[0],
    pointB: { x: 0, y: -10 },
    stiffness: 0.9
});

Step 5: Add Elements to the World

Finally, add the rope composite and the anchor constraint to your world instance:

Composite.add(engine.world, [ropeSegments, anchor]);

Complete Working Example

const engine = Engine.create();
const render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        wireframes: false
    }
});

const group = Matter.Body.nextGroup(true);

// 1. Create segments
const rope = Composites.stack(400, 100, 1, 12, 0, 15, function(x, y) {
    return Bodies.rectangle(x, y, 8, 20, {
        collisionFilter: { group: group }
    });
});

// 2. Chain segments together
Composites.chain(rope, 0, 0.5, 0, -0.5, {
    stiffness: 0.9,
    render: { type: 'line' }
});

// 3. Anchor the top segment
const anchor = Constraint.create({
    pointA: { x: 404, y: 90 },
    bodyB: rope.bodies[0],
    pointB: { x: 0, y: -10 },
    stiffness: 0.9
});

// 4. Add to world
Composite.add(engine.world, [rope, anchor]);

Render.run(render);
Runner.run(Runner.create(), engine);

By altering the stiffness parameter in Composites.chain and adjusting the dimensions of the stack bodies, you can simulate everything from a heavy industrial chain to a flexible string.