# Relève des agents — système audio

Mis à jour : 2026-09-19. Agent : Claude Opus 5.
État : **implémenté et jouable**. Étapes 1 à 7 du plan livrées, plus un lot 8
de raccordement. Il reste une écoute humaine et 16 évènements sans candidat
dans la banque fournie.

## Ce qui a été fait

Le plan de référence reste [plan-systeme-audio.md](plan-systeme-audio.md).
L'usage courant est décrit dans [systeme-audio.md](systeme-audio.md).

| Étape | Livré | Commit |
| --- | --- | --- |
| 1. Contrat et migration | `data/audio_contract.json` (80 évènements), schéma **71**, migration prouvée sans perte | `8aee4d2` |
| 2. Résolveur et directeur | `audio_resolver.gd`, `audio_director.gd`, bus + volumes, 79 clips importés | `3162453` |
| 3. Édition | module `audio_editor.js`, onglet **Sons**, sections sur 6 types de fiche | `f195b33` |
| 4. Gameplay | joueur, monstres, restaurant, donjon, interface ; mouchard d'enregistrement | `16e0aeb` |
| 5-6. Contextes et peuplement | 42 évènements, 4 contextes, 7 biomes, 2 armes ; rapport de couverture | `5e8320b` |
| 7. Documentation | `systeme-audio.md`, README du gestionnaire, relève | `0f89fab` |
| 8. Audit de raccordement | 17 évènements configurés que rien n'émettait, raccordés ; garde permanente | — |

La liste des évènements n'existe **qu'une fois**, dans `data/audio_contract.json`,
lu par PHP et par Godot. Le projet a déjà payé le prix de deux listes jumelles
qui divergent (les états d'animation) ; c'est la raison de ce choix.

## La leçon du lot 8

L'auteur a entendu ce qu'aucun contrôle ne voyait: la course comique et l'achat
d'amélioration étaient **configurés mais jamais émis**. La page de config les
montrait remplis, la publication les acceptait, le jeu se taisait — et la scène
de contrôle Godot passait au vert, puisqu'elle ne peut pas savoir qu'un
évènement n'a aucun appelant.

`python tools/audio_wiring_audit.py` relit désormais le code ET les données et
compare les deux listes. Il tourne avec `--area audio`, et **un évènement
configuré sans émetteur fait échouer la zone**. Le rapport est dans
[audio/raccordement.md](audio/raccordement.md).

Ce qui avait été oublié: tout le départ comique, les achats (amélioration,
console, embauche), les refus d'achat, les portes du restaurant, le pourboire,
les deux évènements de projectile, les pas de monstre, et cinq évènements
d'interface (retour, navigation, ouverture, fermeture, curseur de volume).

Une règle en est sortie, tenue en un seul endroit: **un geste, un son.** Fermer
un panneau faisait parler le bouton *et* le panneau; le directeur garde le
geste et tait ce qui suit dans la même image.

Deux évènements ont été retirés des données plutôt que d'inventer un
déclencheur: `player_projectile_wall` (les projectiles de ce jeu n'entrent en
collision avec aucun mur, ils expirent à leur portée) et `restaurant_purchase`
au sens « meuble acheté » — le mobilier se débloque par amélioration, et c'est
elle qui parle. L'évènement sert maintenant aux achats de la console.

## Ce qui reste

1. **Écouter.** Aucun clip n'a été entendu : les affectations reposent sur les
   noms, les métadonnées et les durées. C'est le seul point que les contrôles ne
   peuvent pas couvrir. Parcours conseillé : accueil → options/mute → restaurant
   (cuisson, service, lavage, achat) → départ → salle (attaques, dash, dégâts,
   mort) → autre salle du même biome → autre biome → retour.
2. **16 évènements sans son**, nommés un par un dans
   [audio/couverture.md](audio/couverture.md) avec leur déclencheur. Leur point
   d'accroche existe dans le jeu : il suffit d'affecter un son. Les manques les
   plus visibles : `player_interact`, `enemy_spawn`, `restaurant_pickup` /
   `_drop`, `dungeon_room_enter` / `_cleared`.
3. **`player_death` réutilise le cri de blessure**, plus bas et plus lent, faute
   d'un vrai son de mort. À remplacer en priorité.
4. **`ui_hover` est volontairement vide** : le plan demandait un survol discret
   et désactivable ; mieux vaut rien qu'un tic à chaque mouvement de souris.

## Constats à ne pas reperdre

- **Aucun preset d'export n'existe** dans le projet. La vérification demandée par
  le plan (les assets audio référencés par chaîne doivent survivre à l'export)
  est donc sans objet aujourd'hui. À refaire le jour où un preset est créé : les
  clips ne sont référencés par aucune scène, seulement par le JSON.
- **Un flux compressé n'est pas rendu par `stop()`** : sa lecture vit encore
  quelques images sur le fil audio. Les quatre contrôles Godot libèrent donc
  l'audio avant de quitter. Sans cela, « resources still in use » apparaissait
  une fois sur quatre et rendait le diagnostic inutilisable.
- **Trois tests de navigateur échouent sur `reset_draft`**
  (`balance_browser`, `page_section_config_browser`,
  `reference_navigation_browser`). Ils assertent que la navigation n'écrit
  jamais ; `initialize()` appelle bel et bien `reset_draft` au chargement, et le
  commentaire du code assume ce prix. Ce sont les **tests** qui sont périmés par
  rapport à la décision, pas le code. Vérifié rouge avant ce chantier.
- **`upgrade_families_test`** échoue sur `todo_copy_2`, encore nommé
  « pas sur - copie » dans les données. Antérieur, et c'est un choix d'auteur.
- **`bulk_workbook_test`** échoue sous le runner seulement : il lance `php -n`,
  donc sans l'extension `zip`. Le test passe avec un php normal.
- Le classeur Excel est **export seul** : aucune réécriture automatique vers le
  JSON, donc aucun aller-retour ne peut perdre les champs audio.

## Ligne de base du chantier

`gameplay` : **51 échecs nommés**, mesurés à `07f6401` avant tout travail audio,
et identiques après. Ne pas les confondre avec une régression ; ne pas non plus
les comparer à un relevé pris après une partie, la sauvegarde change le compte.

`visuals`, `flow`, `persistence`, `audio` : verts.

## Commandes

```powershell
python tools/dev/dev.py check --area audio     # contrat, héritage, tirage, hooks
python tools/audio_import.py                   # import idempotent depuis la banque
php tools/game-data-manager/audio_publish_catalogue.php
php tools/game-data-manager/audio_populate.php # n'écrase jamais un réglage d'auteur
python tools/audio_coverage.py                 # réécrit docs/audio/couverture.md
python tools/audio_wiring_audit.py             # configure mais jamais émis, et l'inverse
```
