# Le réseau à branches (phase 4, tâches 4.1 à 4.5)

Proposition du 06/10/2026, validée par l'auteur le jour même, construite le
07/10 (voir « Ce qui est construit », en bas). Elle traduit les décisions de
l'auteur (vraies branches, plusieurs portes visibles, une salle revisitée garde
quelques traînards, la rame et la carte entre stations reliées) en un modèle
de données et en changements de moteur.

## Ce que faisait le moteur avant le réseau

- La course retient trois choses, en mémoire seulement (une plongée ne se
  sauvegarde pas en cours de route) : la dimension, la case (`run.level`) et
  la salle tirée pour cette case (`run.room_id`).
- Chaque salle a deux bandes : l'entrée (mur ouest, ou nord), qui ramène au
  restaurant, et la sortie, au bout de son axe (est, ou sud).
- La sortie mène à la case suivante, à une case précise (`exit_level`), ou rend
  la main à la case remplacée (sortie 0 d'une salle spéciale : un détour). La
  salle suivante se colle au mur de sortie, et le héros y entre à pied.
- Le pont 3D ouvre les murs aux deux bandes ; l'objectif du HUD dit « salle
  (case/total) ».

## Le modèle proposé

### 1. La colonne reste l'épine

Les cases (`level`) et les salles spéciales gardent leur sens. Une salle de
branche (une station, un tunnel, le Mont de D3, la Ville souterraine de D4)
n'a pas de case : comme une salle spéciale, elle n'existe que par les portes
qui y mènent. Rien de ce qui repose sur les cases ne casse : les scripts, les
références, le décor, les contrôles.

### 2. Les portes d'une salle

Un champ neuf, `exits`, liste les portes d'une salle. Sans lui, la salle garde
sa porte unique d'aujourd'hui. Chaque porte dit :

| Champ | Sens |
|---|---|
| `side` | le mur : est, sud, nord ou ouest |
| `to` | où elle mène : `next` (la case suivante, comme aujourd'hui), `level` (une case précise), `room` (une salle précise), `back` (la salle d'où l'on vient), `travel` (la rame, en phase 6) |
| `room` / `level` | la salle ou la case visée, selon `to` |
| `label` | ce que la porte affiche : « Vers la surface », « Tunnel »… |
| `conditions` | ce qu'il faut pour qu'elle s'ouvre ; sinon elle reste visible et dit ce qui manque, en rouge, comme une porte à objet |

À la construction (07/10), une porte tient **tout son mur**, comme la sortie
d'avant le réseau : deux portes ne partagent jamais un mur, une salle en a
quatre au plus. La place le long du mur (`at`), proposée d'abord, est retirée :
le pont 3D, le relief et le décor savaient déjà ouvrir un mur entier, et un
champ que rien ne lit aurait été une donnée morte.

La porte choisie décide du mur où la salle suivante se colle, et donc du mur
par lequel on y arrive.

### 3. Le chemin parcouru

La course retient en plus la pile des salles traversées (`run.trail`), avec la
case de chacune. `back` remonte cette pile. Une salle de branche hérite la case
de la salle d'où l'on y est entré ; ressortir à la surface reprend la colonne
là où l'on l'avait quittée, ou plus loin si la porte le dit (un raccourci).

### 4. Une salle revisitée

La course retient aussi les salles déjà nettoyées (`run.cleared`). Y revenir
pendant la même course :

- quelques traînards : la première vague de la salle, réduite par une
  statistique neuve, `revisit_wave_ratio` (proposé : 0,25, au moins une
  créature) ;
- pas de nouvelle récompense, pas de nouveau crochet `on_cleared`, et les
  coffres déjà ouverts le restent.

### 5. La rame

Une porte `travel` (phase 6) ouvre la carte du monde ; on y choisit une
station déjà reliée, selon ses conditions. Le modèle la prévoit dès
maintenant pour que les données n'aient pas à changer.

### 6. Le retour au restaurant

La bande d'entrée de chaque salle reste le retour au restaurant, à sa place
d'aujourd'hui (mur ouest, ou nord). Les portes vers d'autres salles se posent
sur les autres murs, ou ailleurs sur le même mur, sans le recouvrir.

## Ce que le moteur doit changer

- **`dive_map.gd`** : lire `exits`, résoudre une porte (`next`, `level`,
  `room`, `back`), tenir la pile et les salles nettoyées, et garder les
  remplacements et les détours d'aujourd'hui.
- **`dungeon.gd`** : une porte, un objet interactif, autant que la salle en
  déclare ; le passage se colle au mur de la porte choisie (les quatre murs,
  plus seulement est et sud) ; les vagues réduites d'une salle revisitée.
- **Le pont 3D** : ouvrir chaque mur à la place de chaque porte, avec son
  étiquette.
- **Le HUD** : une salle de branche affiche son nom, sans « case/total ».
- **Les données** : le champ `exits` dans `data_catalog.gd`, la validation
  PHP, l'outil (un éditeur des portes d'une salle), et la statistique
  `revisit_wave_ratio` dans les deux fichiers.
- **Les contrôles** : un contrôle neuf du réseau (aller, revenir, revisiter,
  une porte fermée qui dit ce qui manque), et la mise à jour de `passages`, qui
  suppose deux bandes.

## Ce que deviennent les stations de la D1

Elles restent des détours (une salle spéciale, sortie 0) jusqu'à la phase 5,
puis deviennent de vraies salles de branche : l'entrée murée devient une
porte qui exige la passe et mène à la station, et la station a deux portes,
« Remonter » (`back`) et le tunnel, barré par des débris.

## Les réponses de l'auteur (06/10)

1. **Le retour au restaurant** : la bande d'entrée seulement à la surface et
   sur les chemins évidents. Un champ neuf de la salle, `retreat_band`, le dit
   (vrai par défaut, faux pour une station ou un tunnel). Sous terre, une
   porte peut donc occuper le mur d'entrée. Et l'on peut toujours mettre fin à
   la plongée depuis le menu de pause, au prix d'un KO : le sac de plongée se
   solde au taux d'assurance, quand la bande de retour le rend en entier.
2. **Les traînards** : un quart de la première vague, au moins une créature
   (`revisit_wave_ratio` = 0,25).
3. **Une salle revisitée** : ni récompense ni coffre neuf. Pour faire simple,
   une salle revisitée ne fait plus apparaître ses coffres ni ses objets à
   casser, ouverts ou non.
4. **Revenir en arrière** : seulement par les portes posées (`back`), pas
   partout.

L'ordre de construction suit le modèle : les données, puis la carte de la
plongée, puis les portes et le passage, la revisite, le menu de pause, le HUD,
le pont 3D, et enfin les contrôles et l'outil.

## Ce qui est construit (07/10)

- **La carte de la plongée** (`dive_map.gd`) : `exits_of()` rend les portes
  d'une salle, ou la porte unique d'avant quand elle n'en déclare pas ;
  `peek_exit()`, `preview_exit_room()` et `advance_exit()` résolvent une porte
  par son rang. Une porte dont les conditions manquent est `LOCKED`. Le chemin
  (`run.trail`) s'allonge à chaque porte et se remonte par `back` ; une salle
  quittée par une porte entre dans `run.cleared`.
- **Le donjon** (`dungeon.gd`) : une bande par porte, la première étant celle
  de la scène ; le retour sur le mur d'arrivée si la salle l'offre et qu'aucune
  porte ne tient ce mur. Les portes parlent le protocole des postes indexés du
  restaurant (`station_index` = leur rang). Le passage colle la salle suivante
  au mur de la porte prise, sur les quatre murs. Une porte reprise pendant que
  l'ancienne salle s'enfonce n'est plus ignorée.
- **La revisite** : un quart de la première vague (au moins une créature), qui
  ne compte pas au quota ; ni coffre ni objet à casser ; ni récompense, ni
  compteur, ni crochet `on_cleared`. Le décor, les portes à objet et les
  personnages restent. La salle s'annonce : « déjà nettoyée ».
- **La retraite** : « Mettre fin à la plongée », dans le menu de pause de toute
  plongée, demande confirmation puis solde le sac au taux d'assurance, comme un
  KO. « Sauvegarder et quitter » coûte de même dans une salle sans bande de
  retour, et rend tout ailleurs, comme avant.
- **Le HUD et le pont 3D** : une salle de branche affiche son nom seul ; chaque
  mur à porte s'ouvre en 3D, et la brume porte l'étiquette avec la flèche de son
  mur.
- **L'outil** : un éditeur des portes dans la fiche d'une salle, la case « bande
  de retour », le rappel des salles dont une porte mène ici, et le refus de
  supprimer une salle qu'une porte vise encore.
- **Les contrôles** : `network` (neuf, sur des salles d'essai), `passages` mis à
  jour, `room_editor_test.js` et `room_exits_validation_test.php`.

Restent ouverts :

- la rame (`travel`) : acceptée par la donnée, fermée en jeu jusqu'à la phase 6 ;
- une bande de retour gardée par un boss (`retreat_locked`) se contourne encore
  par « Sauvegarder et quitter », comme avant le réseau : la question n'a pas été
  tranchée ;
- les stations de la D1 restent des détours jusqu'à la phase 5, où elles
  deviendront de vraies salles de branche.
