# Le système sonore

Référence d'usage. Le mandat d'origine et son analyse restent dans
[plan-systeme-audio.md](plan-systeme-audio.md) ; l'état de la couverture est
regénérable avec `python tools/audio_coverage.py`.

## La règle qui explique tout le reste

**Un son n'est jamais une règle du jeu.** Le directeur ne décide d'aucun dégât,
d'aucun déplacement, d'aucune récompense, et aucun appelant n'a le droit de
faire d'un son une condition de réussite : `play_event` rend `true` ou `false`,
et ce retour ne sert qu'au diagnostic.

Le corollaire est l'invariant le plus important du système : **le hasard du son
est séparé de celui du jeu**. Le directeur tire dans son propre
`RandomNumberGenerator`. Couper le son ne décale donc pas d'un seul tirage les
dégâts, le butin ou le choix d'une attaque — et le contrôle le vérifie en
comparant quarante tirages avec et sans activité sonore.

## Où vivent les réglages

| Emplacement | Ce qu'il porte |
| --- | --- |
| `data/audio_contract.json` | Les 94 évènements (dont, depuis le 07/10, le tic d'une salle en rythme et l'écho du berimbau ; depuis le 14/10, les planches brisées et la barrière du métro), leurs bus, leurs défauts techniques. **Ce n'est pas une donnée d'auteur** : c'est le contrat du code, lu par PHP *et* par Godot. |
| `audio_clips` | Le catalogue : un identifiant réutilisable par fichier. |
| `audio_defaults.events` | Ce qui joue quand personne au-dessus n'a rien dit. |
| `audio_defaults.contexts` | Musique et ambiance de l'accueil, de l'intro, du restaurant et du donjon. |
| `player_configs[…].sounds`, `weapons[…].sounds` | Joueur et armes. |
| `enemies[…].sounds`, `.levels[…].sounds`, `.attacks[n].sounds` | Monstre, variante de niveau, **et chaque ligne d'attaque**. |
| `enemies[…].audio` | Musique de combat : devant la salle tant que le monstre est debout. |
| `customer_profiles[…].audio` | Musique d'un client : devant le restaurant tant qu'il est attablé. |
| `biomes[…]` et `rooms[…]` : `.audio`, `.sounds` | Deux canaux continus, plus les évènements de salle. |
| `story_scenes[…].audio`, étape `audio` | Musique et ambiance d'une scène, posées par-dessus le lieu le temps qu'elle joue. |

La configuration d'une attaque vit sur la **ligne**, jamais sur le pattern :
deux monstres qui partagent un pattern doivent pouvoir sonner différemment, et
deux lignes du même monstre aussi.

## Hériter, se taire, personnaliser

Chaque évènement se règle avec trois choix, et un seul :

- **Hériter** — chercher au niveau suivant. C'est l'état par défaut, et le
  gestionnaire affiche *ce qui s'appliquerait réellement* et d'où ça vient.
- **Silencieux** — un choix, pas un échec. La recherche **s'arrête** : taire une
  attaque ne réveille pas le son du monstre à sa place.
- **Personnaliser** — cette configuration, entière. Ses variantes ne fusionnent
  jamais avec celles du parent.

Une liste personnalisée vide est **refusée à la publication**. C'est voulu : un
héritage tacite y serait indiscernable d'un oubli.

Ordre de résolution, du plus précis au dernier recours :

| Demandé | Ordre |
| --- | --- |
| Attaque de monstre | ligne d'attaque → monstre (variante de niveau comprise) → `enemy_attack_*` |
| État de monstre | monstre → `enemy_*` |
| Attaque du joueur | arme → joueur → `player_attack_*` |
| Blessure, mort, pas du joueur | joueur → `player_*`. **Aucune surcharge par l'arme.** |
| Évènement de salle | salle → biome → `dungeon_*` |
| Musique / ambiance, donjon | (scène en cours →) monstre debout → salle → biome → contexte |
| Musique / ambiance, restaurant | (scène en cours →) client attablé → dimension → contexte |

## Musique de présence : un monstre, un client

Bob le cheval a ouvert ce mécanisme. Sa chanson de combat vit sur **sa fiche**,
pas sur une salle : elle passe devant la salle dès qu'il apparaît — duel, cachette
ou route de service, peu importe — et la salle reprend la main à sa chute. Le
premier monstre arrivé qui en porte une l'emporte. Un corps resté à terre ne
compte plus, et une créature qu'une scène fait sortir rend aussi la main.

Au restaurant, un client attablé pose de même sa musique sur la salle. En chemin
ou dans la file, il ne change rien. Quand la scène et la présence portent le même
réglage, le morceau continue sans être relancé de l'une à l'autre.

La musique de combat se règle sur la fiche de base du monstre, jamais sur un
niveau.

## Musique et ambiance d'une scène

Une scène — dialogue au restaurant, au donjon, ou prologue — se pose
**par-dessus** le lieu où elle joue, canal par canal. Elle ne sait pas d'avance
si ce sera le restaurant ou le donjon : « hériter » y veut dire « ce que le lieu
joue déjà », et ce morceau continue sans être relancé.

- **La fiche de la scène** règle les deux canaux dès son début.
- **Une étape `audio`** change *un* canal pour la suite : un morceau,
  le silence, ou « hériter », qui rend ce canal au lieu en pleine scène. Elle
  ne fait pas attendre ; le fondu se fait pendant les étapes suivantes. Les
  choix et les « Aller à » ne jouent que les étapes réellement parcourues.
- **À la fin**, passée ou non, le lieu reprend **son morceau à la seconde où la
  scène l'avait interrompu**, et le morceau de la scène s'efface à son propre
  fondu, pas à celui du lieu (dix secondes au restaurant).
- **Un quart de seconde de grâce** sépare la fin d'une scène du retour au lieu :
  une scène enchaînée aussitôt avec la même musique ne la relance pas.
- Un changement de salle pendant la scène met le lieu à jour sous elle, sans la
  faire sauter.

Le directeur porte cette couche (`begin_scene_audio`, `set_scene_channel`,
`end_scene_audio`) ; le lecteur de scènes est son seul appelant.

## Poids, probabilité, garde-fous

Le **poids** choisit une variante parmi les autres. Ce n'est ni un volume ni une
chance de déclencher l'évènement — c'est la confusion la plus courante.
La **probabilité** s'applique une seule fois à l'évènement logique.

`cooldown_seconds`, `max_instances` et l'anti-répétition sont portés par le
triplet *(scène, émetteur, évènement)*. Chaque monstre a son identité
d'émetteur : une meute ne partage pas un quota de voix, et le plafond d'un
fourneau n'étouffe pas son voisin.

L'anti-répétition écarte le dernier clip joué **s'il reste autre chose** ; avec
une seule variante elle la conserve, plutôt que de produire un silence.

## Ce qui ne doit jamais se produire

- **Un son par image.** Une zone d'attaque qui dure est republiée à chaque
  image : c'est l'*index du bloc*, gardé pour la séquence, qui dit s'il s'agit
  d'une nouvelle frappe.
- **Un son sur une action refusée.** I-frames, stamina manquante, passage
  fermé : le geste a eu lieu, l'action non. Certains ont leur propre évènement
  de refus ; aucun ne joue celui de la réussite.
- **Deux sons pour une même fin.** `attack_interrupt` dit l'annulation,
  `attack_end` la fin normale. Une mort remplace la blessure, et ne sonne
  qu'une fois même si `die()` est rappelé.
- **Une boucle orpheline.** Toute boucle porte un jeton de scène et meurt avec
  elle. Les sons ponctuels, eux, finissent : ils appartiennent au directeur, pas
  au monstre détruit.
- **Rejouer l'histoire.** Charger une sauvegarde ne rejoue pas les ventes, les
  dégâts ou les cuissons du temps écoulé.

## Coup refusé, coup résisté

Deux refus distincts, deux sons distincts. `enemy_shield_block` dit une
**protection** : bouclier de phase ou fenêtre d'invulnérabilité d'un geste.
`enemy_immune_hit` et `player_immune_hit` disent une **nature** : la cible
résiste à 100 % aux types du coup (résistance 0), et le joueur doit comprendre
qu'il faut changer d'arme. Les deux s'accompagnent d'un « 0 » à l'écran; aucun
ne joue la blessure. Clips de départ : ricochets métalliques (monstre) et
`Reflect` (héros), choisis sur leur nom, **pas encore écoutés**.

## Volumes

`Master` ← `Music`, `Ambience`, `SFX`, `UI`. Le volume principal existant est
conservé ; les quatre volumes de catégorie s'ajoutent sous lui. Couper le
principal n'écrase pas le réglage des enfants, et un fichier de réglages
antérieur aux catégories garde leurs défauts — rien ne devient muet à la mise à
jour.

Trois gains distincts, qu'il ne faut pas confondre : le gain du clip (dans la
variante), le gain de fondu (transitoire, au directeur) et le volume utilisateur
(sur le bus).

## Ajouter des sons

**Le dossier est la vérité.** Déposer un fichier `.mp3`, `.ogg` ou `.wav` dans
`assets/audio/music/`, `assets/audio/ambience/` ou `assets/audio/sfx/`, puis
recharger le gestionnaire : il est choisissable. Son type vient du sous-dossier,
son identifiant du nom du fichier (`country side.mp3` → `country_side`). La liste
`audio_clips` se reconstruit à chaque ouverture du gestionnaire
(`sync_audio_clips_with_folder`). Un fichier retiré quitte la liste ; s'il est
encore employé, il reste et le gestionnaire le signale. Le jeu le connaît à la
publication suivante, une fois Godot passé dessus pour l'importer.

Pour piocher dans une grosse banque hors projet (RAREVGSFX) :

1. Déposer les fichiers, ou compléter `docs/audio/selection-retenue.csv` au
   format de la présélection, puis `python tools/audio_import.py`. L'import est
   idempotent et dédoublonne **par contenu**, pas par nom.
2. `php tools/game-data-manager/audio_publish_catalogue.php` publie le catalogue
   sans écraser les noms d'affichage ni les étiquettes modifiés à la main.
3. Affecter dans le gestionnaire, onglet **Sons** pour les valeurs générales, ou
   dans la fiche concernée.
4. `python tools/audio_coverage.py` réécrit le rapport de couverture.

Les chemins du maître sont **toujours** `res://assets/audio/…`. Un chemin hors
du projet est refusé à la publication : il marcherait sur un seul poste.

## Éprouver

`python tools/dev/dev.py check --area audio` couvre le contrat, le catalogue,
l'héritage, le tirage pondéré, les garde-fous du directeur, la couche des
scènes et leur reprise, l'isolation des tirages et les points d'accroche d'un
vrai monstre. Le mouchard
(`begin_recording` / `recorded_events`) note ce qui a été **demandé** et ce qui
a **démarré** : c'est ce qui permet d'éprouver ces règles en headless, sans
périphérique audio.

Ce que ces contrôles ne disent pas : si le résultat **sonne juste**. Aucun clip
de la banque n'a été écouté ; les affectations reposent sur les noms, les
métadonnées et les durées. Une écoute reste nécessaire.
