# Caves and cutters

> Carve generated caves, sculpt the ground as voxels, and cut rooms, ramps and tunnels with objects, scripts and Blueprints.

Source: https://feather-engine.com/docs/world/caves-and-cutters/

The landscape is a heightfield, but you can carve into it as a volume. Volume edits are stored as
0.5 m voxels in 8 m columns, so you get real walls, overhangs, arches and tunnels with a roof.
Carved ground renders and collides like the rest of the terrain, saves with the landscape, and can
be dug further, blasted open or flooded.

There are four ways to carve: generate a cave system, sculpt voxels by hand, place a **Terrain
cutter** object, or call a carve function from a script or Blueprint.

## Generate caves

1. Open the **Landscape workspace** (**Window → Landscape**) and expand **Caves**.
2. Set the recipe.
3. Click **Place caves — click the ground**, then click the middle of the cave area in the
   viewport. Press **Esc** to cancel.

Entrances open on the surface, so the player can walk in. The ground on top keeps its grass and
trees. The same recipe on the same ground always carves the same caves; change **Seed** for a
different layout. Each placement is one undo step. Caves are carved into the level, so you cannot
place them during Play.

| Setting | Field | Panel range | Command range | Default |
| --- | --- | --- | --- | --- |
| Area radius m | `radius` | 8–200 | 8–400 | 60 |
| Tunnels | `tunnels` | 1–24 | 1–48 | 4 |
| Tunnel length m | `length` | 8–160 | 8–400 | 70 |
| Tunnel size m | `size` | 1–6 | 1–8 | 2.2 |
| Depth m | `depth` | 3–40 | 3–60 | 9 |
| Caverns | `caverns` | 0–1 | 0–1 | 0.5 |
| Entrances | `entrances` | 0 to Tunnels | 0 to `tunnels` | 1 |
| Winding | `winding` | 0–1 | 0–1 | 0.5 |
| Rough walls | `roughness` | 0–1 | 0–1 | 0.5 |
| Seed | `seed` | — | 0–4,294,967,295 | 1 |

**Tunnel size** is the tunnel radius; tunnels swell and narrow around it. **Caverns** sets how
often a tunnel opens into a wide cavern. **Depth** is measured below the surface.

:::tip
The `landscape.caves` command returns entrance positions, cavern floor centres, a floor point
inside each tunnel, and a ready spawn position in each cavern. Use them to place loot, lights,
enemies or the player start.
:::

## Sculpt voxels by hand

The **Voxel sculpt** section of the Landscape workspace adds or removes balls of ground.

1. Set **Ball radius m** (0.5–8 m, default 1.5 m).
2. Click **Carve** to remove ground or **Add** to build it up.
3. Click the ground repeatedly. Clicks also hit cave walls and overhangs, so you can shape arches
   and tunnels. Press **Esc** to stop.

Each click is one undo step.

## Cut with an object

A **Terrain cutter** component carves the ground with its object's collider box, or with the ball
inside that box. Use it to sink a room, cut a ramp, a moat or a tunnel mouth, or put it on
something that moves to make it dig.

1. Place an object and scale and rotate it to the shape you want.
2. In the Details panel, click **Add Component → Terrain cutter**.
3. Set the fields below.
4. Click **Carve terrain now** to bake the cut into the level's ground, or **Carve & remove box**
   to bake it and delete the object. Both are undoable.

If you do not bake it, the cutter carves during Play according to **When**.

| Field | Options or range | Default | Description |
| --- | --- | --- | --- |
| Does | Carve / Add ground | Carve | Add ground fills instead of removing |
| Shape | Box / Ball | Box | Ball cuts the ball inside the box. A sphere collider always cuts a ball |
| Round edges | 0–5 m | 0 | Softens the cut |
| When | Play starts / While moving / Only when asked | Play starts | When the cutter carves during Play |
| Hide in game | On/off | On | Hides the object during Play. Static objects also lose their collider, so the cutter acts as a pure terrain tool |
| Ground toughness | 0–1 | 0.3 | While moving only. How much speed a physics body loses as it digs: 0 digs forever, 1 stops at once |

New cutters pick sensible defaults: on a **Dynamic** physics body, **When** starts at **While
moving** and **Hide in game** is off; on other objects the cutter carves once when Play starts and
stays hidden.

### Digging physics bodies

A dynamic body with a **While moving** cutter digs ahead of itself while it moves faster than about
3 m/s. The ground slows it according to **Ground toughness**, so a falling ball or meteor bores a
hole on impact and stops once it slows down, instead of sinking forever. Non-physics objects with
**While moving** carve wherever they go, which suits drills and burrowing creatures moved by
scripts or animation.

Ground carved by cutters during Play is restored when you press **Stop**.

## Example: carve a tunnel entrance into a hillside

You'll bake a box-shaped tunnel into the side of a hill, open at the bottom of the slope and roofed
further in. Start from the hilltop project built in the [Landscape
example](/docs/world/landscape/#example-a-level-building-plot-on-a-hilltop): a hill centred at
X 30, Z 0 whose west slope climbs from about 4 m at X 10 to 13 m at X 18.

1. Choose **Add → Cube** and name it `Tunnel mouth`.
2. In **Details → Transform**, set **Location** to `14`, `-1.5`, `0` and **Scale** to `12`, `3`, `3`.
   The height is relative to the ground, so the box sits 1.5 m into the slope and runs along X into
   the hill.
3. Click **+ Add Component → Terrain cutter**. Leave **Shape** on **Box** and set **Round edges**
   to `1` m.
4. Click **Carve & remove box**. The cut is baked into the ground and the cube is deleted, as one
   undo step.

Fly the camera to the west side of the hill: the slope opens into a 3 m wide passage whose roof
closes over it a few metres in.

Do the same from the command line, in the same project (the cube is object 1 in a project with no
other objects):

```bash
feather-cli --workspace ./hill-plot --project project.feather.json command scene.add \
  --json '{"kind":"Cube","name":"Tunnel mouth","position":[14,-1.5,0]}' --save project.feather.json

feather-cli --workspace ./hill-plot --project project.feather.json command scene.update \
  --json '{"id":1,"patch":{"scale":[12,3,3],"terrain_cutter":{"shape":"Box","soften":1}}}' \
  --save project.feather.json

feather-cli --workspace ./hill-plot --project project.feather.json command landscape.carve_object \
  --json '{"id":1,"remove":true}' --save project.feather.json
```

Check it worked: the `landscape.carve_object` response has `"removed": true` and a `cut` with
`"half": [6.0, 1.5, 1.5]`. Then read the ground heights along the tunnel:

```bash
feather-cli --workspace ./hill-plot --project project.feather.json command landscape.inspect \
  --json '{"points":[[12,0],[18,0]]}'
```

At X 12, inside the open mouth, the height drops from about 5.5 m to the tunnel floor at about
3.4 m. At X 18 it still reads the hill surface, about 12.7 m, because the roof is intact there.

## Carve from scripts and Blueprints

Scripts can edit the ground at runtime. Every function below is also available as a Call node in
Blueprints, in the **Destruction** group.

| Function | Description |
| --- | --- |
| `carve_box(x, y, z, width, height, depth, yaw)` | Removes an oriented box of ground; `yaw` in degrees |
| `fill_box(x, y, z, width, height, depth, yaw)` | Adds an oriented box of ground |
| `carve_object(id)` | Carves with that object's box, or its terrain cutter's shape. Use it with **Only when asked** cutters |
| `generate_caves(#{...})` | Carves a cave system. Takes the same optional fields as `landscape.caves` |
| `generate_caves_at(x, z, radius, seed)` | Carves caves with the default recipe at a position |
| `dig(x, y, z, radius, depth)` | Lowers the surface and heaps the soil beside the hole |
| `fill(x, y, z, radius, height)` | Adds soil |
| `dig_trench(x1, z1, x2, z2, width, depth)` | Cuts a straight-walled trench between two points |
| `dig_tunnel(x1, y1, z1, x2, y2, z2, radius)` | Cuts a tunnel between two points |
| `crater(x, y, z, radius, depth)` | Blows a crater into the ground |

```rust
// Open a cellar under this object when Play begins.
fn start() {
    let p = position();
    carve_box(p[0], p[1] - 2.0, p[2], 6.0, 4.0, 6.0, 0.0);
}
```

Runtime cuts rebuild only the terrain chunks they touch, and refresh fluids and navigation. For
blasts, craters and destructible objects, see [Destruction](/docs/gameplay/destruction/).

## Limits

- Volume edits use 0.5 m voxels in 8 m columns, up to 4,096 columns per landscape. A column spans
  at most 100 m vertically.
- Craters and surface digs use a 0.5 m detail grid, up to 400,000 samples.
- A cave recipe can carve at most 4,000 m of tunnel in total (`tunnels` × `length`).
- A box cut must be 0.2–120 m on each axis. A terrain cutter's box is clamped to that size.

## Automate it

This carves a cave system centred on the origin and then bakes object 42's terrain cutter into the
ground, removing the object:

```bash
feather-cli --connect .feather-session.json command landscape.caves \
  --json '{"center":[0,0],"radius":80,"tunnels":6,"length":90,"entrances":2,"seed":11}'

feather-cli --connect .feather-session.json command landscape.carve_object \
  --json '{"id":42,"remove":true}'
```

| Command | Purpose |
| --- | --- |
| `landscape.caves` | Carves a generated cave system and returns entrances, caverns, tunnel points and spawns |
| `landscape.carve_object` | Bakes an object's box or terrain cutter into the ground |
| `landscape.dig` | Digs a hole, trench or tunnel; `mode` `surface` or `volume`, `fill` to add ground |
| `landscape.crater` | Blasts a crater with an optional rim and scorch |
| `landscape.inspect` | With `points`, returns ground heights including craters and digs |
| `scene.update` | Adds or edits a `terrain_cutter` on an object |

`landscape.reset` clears craters and digs along with the other terrain edits. See
[Agents & automation](/docs/agents/overview/) for connecting a live session.
