---
name: ferret-flow
description: Use for moving air and water in Ferret levels: wind, fronts, tornadoes, jets, lee shelters, rivers (channel), baked fields, and flow boxes that solve the flow round bodies (wakes, drag, lift); one field everything reads.
---

# Flow sources

## When to use
A breeze that gusts, a storm front crossing a valley, a tornado that lifts crates, a river that carries logs, a fan, the lee of a hill, wind in a sail.

## The model
Sources (`uniform`, `front`, `vortex`, `jet`, `shelter`, `channel`, `curve`) add up to one field `flow.at(position, time, medium)` for `air` or `water`. Every source is a pure function of position and time, so peers agree without replication. Bodies, vessels, the character and the render read the field; it is not a force on a body.

## Steps
1. Add a `FlowService` to the world (`@ferret/flow`); enable `media` for bodies to feel it.
2. List sources in the level's `physics.flow`, or `edit.physics.flow.set { name, kind, ... }`.
3. A liquid current is a source with `medium: "water"`; bodies in a liquid medium and a surface's `current` (`waterCurrent(field)`) read it.
4. Limit cost with `reach`; move a source with `path` + `speed`; fade it with `level` curves.
5. Commands: `flow.at|set|on|off|move`, `edit.physics.flow.set|remove|list`.

## Check afterwards
`flow.at` at the point returns the expected velocity; a light body reaches the wind speed; a body outside a channel is not moved.

## What usually goes wrong
- Nothing moves: no `FlowService`, `media` not enabled, or the point is outside `reach`.
- A channel's `width` is a 3D distance from its line, so a body at another height than the points sees a thinner profile.
- A water source with `medium` missing is air (the default).
- A character is not pushed: `maxWindAccel` is 0.

## Flow around bodies (flow box)
- Use `FlowBox` / `physics.flowBoxes` where a body must change the wind: a tower's lee, a roof section, a pier in a river. `plane: 'xz'` horizontal, `'xy'` vertical; `cell` sets the cost (about 1 us per cell per step).
- `forces: 'solved'` drives rigid bodies by surface pressure (air boxes only); `coefficients` keeps the media drag and uses the box for the wake.
- Over `maxCells` the box coarsens and reports `degraded`; `sleep` returns the analytic field; `every: n` steps it less often.
- 3d boxes are not built; the box refuses `plane: "xyz"` with that message.

## Files

- `reference/flow.md` — Wind, fronts, vortices, jets, shelters and channels that add up to one field of moving air and water, a pure function of position and time that bodies, vessels, the character and the render can all read.
- `reference/api-flow.md` — every export of `@ferret/flow` with signature and doc comment
- `reference/api-flow-solver.md` — every export of `@ferret/flow-solver` with signature and doc comment
- `reference/api-physics-media.md` — every export of `@ferret/physics-media` with signature and doc comment
- `reference/commands.md` — 23 commands of these packages with their arguments
