# Банки звуков — `$.sound.bank*`

Банк — это набор вариантов одного звука: шаги по траве, попадания, выстрелы.
Игра не выбирает файл вручную, а просит «шаг по дереву», а банк отдаёт
случайный вариант из списка — без повторов подряд.

```js
$.sound.defineBank('step_grass', ['s1.wav', 's2.wav', 's3.wav']);
$.sound.playBank('step_grass', { volume: 0.6 });

$.sound.defineBank('hit', { files: ['h1.wav', 'h2.wav'], volume: 0.9, pitch: 0.05 });
```

---

## 1. Методы

| Вызов | Смысл |
|---|---|
| `defineBank(name, spec)` | описать банк: список файлов или `{ files, … }` |
| `load(data)` | загрузить пачку банков |
| `playBank(name, opts?)` | проиграть случайный вариант; вернёт имя файла или `null` (не сыграно) |
| `bankNames()` / `bankFiles(name)` / `has(name)` / `remove(name)` / `reset()` | реестр |
| `lastPlayed(name)` | какой файл банк играл последним (для тестов и отладки) |
| `$.sound.bank` | сам банк: `files()`, `names()`, `has()`, `remove()`, `reset()`, `load()` |

Настройки банка: `files`, `pitch` (±доля высоты), `volume` (число или
`[min, max]`), `interval` (не чаще, чем раз в секунды), `avoids` (сколько
последних файлов не повторять).

Чистые помощники: `bankFiles(spec)`, `pickBankFile(files, random)`,
`bankVolume(spec)`, `bankPitch(spec)` — их проверяет юнит-тест.

## 2. Правила выбора

* **без повтора подряд**: если вариантов больше одного, следующий не равен
  предыдущему;
* **разброс высоты тона** (`pitch`) применяется к каждому проигрыванию, поэтому
  одинаковые шаги не звучат штампом;
* **вес варианта** задаётся повторением файла в списке.

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

* **банк не грузит файлы заранее**: `playBank` передаёт имя в `$.sound.play`;
  для предзагрузки зовите `$.sound.preload`;
* **только плоские списки**: вложенных банков и категорий нет;
* **случайность — детерминированная**: чистые помощники (`pickBankFile`,
  `bankVolume`, `bankPitch`) без переданного генератора возвращают
  ПРЕДСКАЗУЕМЫЙ результат (первый вариант, нижняя граница диапазона), а
  подсистема `playBank` берёт `fxRandom` — он сеется движком (`--seed`), поэтому
  реплей воспроизводится. Свой генератор можно передать явно;
* **нет приоритетов и лимитов каналов на банк**: за это отвечает `$.sound`.

## 4. Шаги и реплики — отдельно

Шаги по материалу пола (`$.steps`) и реплики NPC (`$.barks`) — соседняя
подсистема со своей страницей: [steps.md](highlevel/steps). Шины, эффекты и
акустика помещений — в [sound.md](highlevel/sound) и [audiobus.md](highlevel/audiobus).
