# "Cookbook: structures, ropes and breaking"

# Cookbook: structures, ropes and breaking

The guides behind these: strength (skill `ferret-physics-strength`), stretch (skill `ferret-physics-stretch`), explosions (skill `ferret-physics-combustion-explosions`), impact (skill `ferret-physics-friction-impact`). Each recipe says what to build and what to expect; the runnable versions, with the numbers they must produce, are in `tests/unit/examples/physics-cookbook-structures-and-ropes.test.ts`.

## 1. What load does this rope hold?

A rope link breaks at `breakStrain`. The strength of a rope held still is `breakStrain × E × area`; with `E = 1e7`, `A = 1e-4` and `breakStrain = 0.25` that is 250 N, about 25 kg.

```ts
const rope = cap.rope({ from: [0, 0, 0], to: [0, -2, 0], segments: 8, mass: 0.5, E: 1e7, area: 1e-4,
                        damping: 30, anchorA: anchor, radius: 0.02, breakStrain: 0.25 });
const load = rope.beads[rope.beads.length - 1];
load.mass = kg; load.invMass = 1 / kg;
```

Hang 10 kg (98 N, a strain of 0.1) and it holds; hang 400 kg and it parts. A load dropped onto the rope breaks it sooner, because the peak force exceeds the weight.

## 2. A shear pin: the weak link that saves the rest

Put a constraint with a known `maxForce` in series with the expensive part. When the load becomes dangerous the pin goes, and the part is saved.

```ts
const pin   = cap.joint({ type: 'rod', a: anchor, b: mid,  maxForce: 1500 });
const chain = cap.joint({ type: 'rod', a: mid,    b: load, maxForce: 6000 });
world.events.on('physics:joint-break', (e) => { /* e.constraint is pin or chain */ });
```

Raise the load slowly: the pin goes first and the strong link survives. Shear pins in a drive line, break-away signposts, a frangible bolt on a stage: the same idea. Report `physics:joint-break` to the player ("the tow rope snapped").

## 3. A crate that breaks only at speed

Damage is the impulse above a threshold, so a gentle brush does nothing and a hard hit breaks it into pieces. The threshold is the `toughness` config, the number of pieces is `pieces`:

```ts
host.config('strength').set('world', 'toughness', 10);      // absorbs 10 N s
host.config('strength').set('world', 'pieces', 5);
world.events.on('physics:break', (e: BreakEvent) => { /* e.pieces */ });
```

A 1 kg crate hitting a wall at 3 m/s gives 3 N s, below the 10 N s it absorbs, and survives; at 20 m/s it gives 20 N s and breaks into five pieces, one `physics:break` event. Per-kind toughness is a config value at entity or zone scope: `host.config('strength').set('entity', 'toughness', 3, 'glass-pane')`. See the strength guide (skill `ferret-physics-strength`) for `threshold`, `scale` and `maxPieces`.

## 4. A bungee that springs back

Elastic up to `yieldStrain`, so it returns to its rest length. Past yield it takes a permanent set; past `breakStrain` it snaps.

```ts
const r = cap.rope({ from: [0, 0, 0], to: [0, -2, 0], segments: 8, mass: 0.2, E: 2e5, area: 1e-4, damping: 8,
                     anchorA: anchor, radius: 0.02, yieldStrain: 3, breakStrain: 6 });
```

A 2 kg jumper stretches below the rest length and settles at `F L / (E A)` longer than it. Raise the weight, or lower `E`, to see the lowest point drop; set `yieldStrain: 0.002` for a copper wire that stays bent. Events `stretch:yield` and `stretch:break` carry the link's name; name the links you care about.

## 5. A wall that breaks under a blast

A body takes a push `I · A` from the blast and breaks when the impulse per area passes its `rupture` value. Set `rupture` low for a plasterboard partition, high for a bunker wall, and the same charge breaks one and not the other.

```ts
const impulse = blastAt(8, 10).impulse;                                     // per m², 10 kg TNT at 8 m
host.config('explosion').set('entity', 'rupture', impulse * 0.5, plaster.id);
host.config('explosion').set('entity', 'rupture', impulse * 4,   bunker.id);
blast.detonate({ at: [0, 0, 0], tnt: 10 });
```

Both bodies are 8 m from the charge. The blast is the same; the materials differ: the partition breaks, the bunker wall holds. The entity-scope values are keyed by entity id here; in a game you set them per material kind from the level data.

## 6. A curtain that hangs and drapes

Cloth is position-based dynamics with a strain limit; a pinned top row makes a curtain, colliders make it drape:

```ts
const curtain = new Cloth({ nu: 20, nv: 20, spacing: 0.05, mass: 0.4, pinned: 'top', origin: [0, 0, 0],
                            u: [1, 0, 0], v: [0, -1, 0], strainLimit: 1.05, iterations: 6, substeps: 2 });
curtain.step(1 / 60);

tarp.colliders.push({ type: 'sphere', center: [0, 0.5, 0], radius: 0.3 }, { type: 'plane', normal: [0, 1, 0], offset: 0 });
```

The curtain hangs about a metre and the strain limit holds. A tarp dropped over a sphere catches on the top of it. A curtain of 400 particles costs well under a millisecond a step; keep cloth to a handful on screen and see stretch (skill `ferret-physics-stretch`) for the budget.
