# Шаги и реплики — `$.steps` и `$.barks`

Шаги по материалу под ногами и короткие реплики NPC — то, что делает сцену
живой. Банк вариантов даёт разброс, поэтому один и тот же шаг не звучит штампом.

```js
$.steps.material('dirt', { files: ['d1.wav', 'd2.wav'], volume: 0.5 });
$.steps.play('dirt');
$.steps.tick(dt, { speed: hero.speed, grounded: true });
$.steps.land('dirt', 220);                  // приземление: сила удара

$.barks.define('wounded', ['ай.wav', 'больно.wav']);
$.barks.use('wounded', { chance: 0.4 });
$.barks.load(data);
```

---

## 1. `$.steps`

| Вызов | Смысл |
|---|---|
| `material(name, spec)` / `has(name)` / `materials()` / `resolveMaterial(name)` | материалы |
| `play(name, opts?)` | проиграть шаг |
| `tick(dt, opts?)` | накопить пройденное и сыграть шаг по страйду |
| `land(name, force)` | звук приземления по силе удара |
| `reset()` | сбросить накопленное |

Константы шага: `STRIDE` (78), `RUN_STRIDE` (96), `MIN_SPEED` (40), `RUN_SPEED`
(260). Чистые функции: `advanceStride`, `stepVolume`, `landVolume`.

## 2. `$.barks`

| Вызов | Смысл |
|---|---|
| `define(name, files)` / `load(data)` | описать банк реплик |
| `pick(name, opts?)` / `use(name, opts?)` | выбрать / выбрать и проиграть |
| `reset()` | сбросить историю |

`barkFits` и `pickBark` — чистые помощники: проверяют шанс и не дают выбрать
ту же реплику дважды подряд.

## 3. Материалы

Материал берётся из мира (`resolveMaterial`) или задаётся явно. Если для
материала нет банка, звук не играет — `fallback()` показывает, что подставлено.

## 4. Ограничения

* **материал не определяется по текстуре**: игра сама сообщает, по чему идёт
  боец (`$.steps.material`), автоматического чтения тайлмапа нет;
* **шаг — один звук**, без слоя обуви и одежды: сложные наборы собираются банком;
* **реплики без текста**: `$.barks` играет звук, субтитры — `$.story`;
* **шаг по воде/траве не переходит между материалами**: смена материала
  мгновенная, без плавного перехода;
* **разброс воспроизводим**: выбор варианта и высота тона берутся из
  `fxRandom` (сеется движком), поэтому реплей воспроизводится; свой генератор
  можно передать в спецификации материала через `rng`.
