Files
Ransom-s-wake/docs/VERTICAL_SLICE_TECHNICAL_PLAN.md
T

938 lines
41 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Verticale jouable — Cadrage technique retenu
## Statut
- Date : 10 août 2026.
- Dernière révision d'implémentation : 16 août 2026.
- État : cadrage approuvé, tranches 0 et 1 implémentées.
- Jalon : verticale jouable, après validation des POC A et B.
- Durée directrice du plan général : quatre à six mois.
- Moteur figé pour le jalon : Godot 4.7.2.
- Références : baselines techniques des POC A et B, design system UI.
Ce document définit ce que la verticale doit prouver, les frontières de son
implémentation et l'ordre de construction. Il ne remplace ni le game design
général ni les baselines des prototypes.
## 1. Question à valider
La verticale doit répondre à une seule question principale :
> Préparer une expédition, resserrer une zone avec le sonar du navire, trouver
> et identifier une épave parmi des leurres, récupérer son objectif puis revenir
> sous contrainte forme-t-il une boucle claire et assez satisfaisante pour
> porter une campagne ?
Les POC ont validé séparément le véhicule et le langage du sonar. La verticale
doit vérifier leur combinaison dans une mission complète avec préparation,
objectif, conséquence et progression.
## 2. Parcours joueur retenu
La verticale utilise le premier navire de la campagne : le bâtiment de
prospection contemporain du précédent opérateur.
1. Consulter le contrat mensonger de la société, le registre public et, si
acheté, le pack d'archives à 500 €.
2. Naviguer sur la carte jusqu'à la zone probable et lancer des relevés du
sonar de surface.
3. Recouper les zones d'écho puis déployer le mini-sous-marin.
4. Suivre le relief tout en surveillant oxygène, batterie, pression et coque.
5. Utiliser manuellement le sonar bathymétrique pour trouver plusieurs épaves
candidates sans marqueur direct.
6. Examiner des indices, consulter le dossier en pause et désigner une cible
présumée sans validation immédiate.
7. Identifier le navire de prospection du précédent opérateur parmi deux leurres
extérieurs légers.
8. Stabiliser le sous-marin, découper une attache et ouvrir un compartiment.
9. Récupérer le module de cartographie, ses données, une pièce mystérieuse et,
si la place le permet, un objet secondaire.
10. Revenir au navire, faire surface à proximité et déclencher `Treuiller`.
11. Remplir manuellement oxygène et batterie, puis vider le panier vers la cale.
12. Analyser les données à bord afin de révéler la zone probable du U-Boot.
13. Rentrer au port, décharger, remettre le module, toucher 1 000 € et vendre
l'objet secondaire.
14. Acheter l'agrandissement de cale de 12 à 18 unités et vérifier son effet.
Durée cible initiale : 15 à 25 minutes pour la plongée réussie et 30 à 45
minutes pour le parcours complet avec port, relevé de surface et débriefing,
hors reprise après échec. Ces nombres seront corrigés par playtest.
## 3. Périmètre obligatoire
### Plongée
- POV intérieur et hublot circulaire.
- Pilotage inertiel avec retour immédiat des commandes.
- Oxygène, batterie électrique, profondeur, pression et intégrité.
- Alarmes texte, couleur et son.
- Estimation de retour compréhensible.
- Sonar manuel progressif, compact et agrandissable.
- Sonar de surface déterministe et imprécis depuis la carte maritime.
- Un terrain conçu à la main avec une route sûre et une route plus risquée.
- Une épave majeure identifiable et deux épaves leurres extérieures légères.
- Un registre public, un pack d'archives facultatif et un dossier comparatif.
- Une interaction de découpe, une récupération et une stabilisation assistée.
- Retour réussi, abandon volontaire et perte du véhicule.
### Métajeu minimal
- Un port illustré donnant accès à l'entreprise nommée, aux Archives
maritimes, au Chantier naval et au Comptoir.
- Un contrat, trois fiches d'épaves candidates et un pack d'archives.
- Une carte maritime, un écran de préparation et les instruments de base du
navire.
- Un débriefing.
- Une remise contractuelle et une vente manuelles.
- Une réparation de coque et une amélioration de cale achetable.
- Une sauvegarde locale versionnée.
### Menus et réglages
- Un menu principal avec Continuer, Nouvelle partie, Réglages et Quitter.
- Un menu pause qui suspend réellement les ticks de plongée.
- Une confirmation explicite avant abandon, retour au menu ou sortie pendant
une plongée.
- Quatre catégories de réglages : commandes, accessibilité, audio et affichage.
- Les états de chargement, sauvegarde absente, invalide ou incompatible.
- La présentation suit `docs/UI_DESIGN_SYSTEM.md` ; les maquettes sous
`Design-Proposal/` restent des références non exécutables.
- Les nouveaux écrans de port, carte, dossier et entretien exigent une itération
de design dédiée ; seules leurs responsabilités fonctionnelles sont figées ici.
### Qualité minimale
- Clavier-souris remappable.
- Textes français structurés pour une future localisation anglaise.
- Taille du texte et réduction des mouvements accessibles depuis les réglages.
- Chargement, sauvegarde et reprise d'une session sans état incohérent.
- Barrière qualité reproductible sur macOS, puis Windows et Linux avant la fin
du jalon.
## 4. Hors périmètre ferme
- Deuxième grande épave.
- Pilotage 3D et physique navale ; la carte maritime limitée de la mission
reste obligatoire.
- Trois ports ou marchés dynamiques.
- Relations de personnages complètes.
- Dialogue à embranchements complexe.
- Plusieurs classes de coque.
- Plusieurs outils de salvage simulés.
- Loadout configurable ; le cutter et le bras requis sont imposés.
- Intérieur complet de l'épave.
- Véritable grotte à plusieurs niveaux ou surplomb complexe.
- Génération procédurale de site majeur.
- Corruption surnaturelle avancée.
- Ballasts, courants et échos géologiques présentés comme contacts prometteurs.
- Doublage, cinématique ou art final.
- Manette certifiée, succès, cloud ou intégration de boutique.
- Import d'une sauvegarde de démo.
Une idée hors périmètre peut être inscrite dans le backlog. Elle ne peut entrer
dans la verticale sans retirer un élément de coût comparable et mettre à jour ce
document.
## 5. Critères de réussite
### Compréhension humaine
- Au moins 8 testeurs sur 10 trouvent l'accès à l'épave en 5 à 10 minutes après
l'arrivée dans la zone de recherche, sans aide orale.
- Au moins 8 sur 10 comprennent la différence entre zone de recherche, écho de
surface, épave non identifiée et épave identifiée.
- Au moins 8 sur 10 comprennent le rapport entre bleu, vert, jaune et hauteur.
- Au moins 8 sur 10 identifient la caisse ou l'anomalie sur le sonar.
- Aucun testeur ne confond oxygène et batterie après le tutoriel.
- Les alarmes sont comprises avant la première perte.
- Au moins 4 testeurs sur 5 souhaitent essayer une seconde mission.
### Boucle de jeu
- Une enquête attentive réduit la recherche locale à moins de dix minutes.
- Le joueur peut expliquer les deux indices ayant motivé son identification et
pourquoi les leurres ne correspondent pas.
- Le retour est une décision anticipable et non une surprise punitive.
- Une première erreur ne rend jamais la mission principale impossible.
- Le passage de la cale de 12 à 18 unités est visible et persiste.
### Technique
- La barrière qualité reste verte à chaque tranche.
- Aucun code de production ne dépend des dossiers des POC.
- Une seule source de vérité existe pour chaque ressource et progression.
- Une sauvegarde V1 peut être chargée après redémarrage du jeu.
- Les références de contenu invalides sont refusées par des tests de contrat.
- Le jeu tient 60 FPS à 1080p sur la machine macOS ARM64 disponible, avec mesure
séparée du coût du sonar.
- Aucun `ERROR`, `SCRIPT ERROR`, avertissement ou objet Godot fuité n'est accepté
dans les parcours automatisés.
## 6. Architecture de production
La verticale suit `docs/ENGINEERING_GUARDRAILS.md` et les ADR acceptés.
```text
game/
domain/
dive/
sonar/
mission/
inventory/
economy/
upgrades/
campaign/
rules/
application/
dive/
sonar/
mission/
navigation/
vessel/
port/
interfaces/
world/
submarine/
vessel/
sonar/
sites/
interactions/
presentation/
cockpit/
sonar/
dossier/
map/
port/
briefing/
debriefing/
settings/
infrastructure/
input/
save/
audio/
localization/
composition/
vertical_slice/
content/
wrecks/
contracts/
evidence/
archives/
items/
rules/
upgrades/
sites/
localization/
```
Le dossier `application/interfaces/` contient les contrats abstraits vers les
adaptateurs externes. Le dossier `application/port/` orchestre les écrans et cas
d'usage du port maritime.
## 7. Propriétaires des états
| État | Propriétaire unique | Lecteurs principaux |
|---|---|---|
| Tick et temps réel | application et adaptateur d'horloge | `DiveSession` via `DiveTick` explicite |
| Oxygène, batterie, coque, pression, alertes et fin de plongée | `DiveSession` du domaine | HUD, audio, débriefing |
| Règles résolues de la plongée | `DiveRulesResolver` du domaine | `DiveSession`, navigation, outils |
| Transform, vitesses et collisions | `SubmarineActor` dans `world` | télémétrie, caméra, capteur |
| Commande de propulsion | cas d'usage de pilotage | adaptateur physique |
| Orientation de la caméra | contrôleur de caméra de présentation | vue cockpit uniquement |
| Observations de collision | adaptateur physique du monde | `DiveSession` |
| Scan courant et précédent | service applicatif sonar | renderer, HUD |
| Échantillons physiques bruts | adaptateur sonar du monde | service applicatif sonar |
| Échos sonar de surface persistants | progression de campagne | carte, préparation, sauvegarde |
| Objectifs, épaves connues et faits observés | `MissionProgress` du domaine | dossier, carte, débriefing |
| Cargaison du panier | `DiveInventory` du domaine | HUD, récupération, débriefing |
| Cale, stockage, argent, dette et améliorations | `CampaignState` du domaine | navire, port, sauvegarde |
| Position et disponibilité du navire | `CampaignState` via `VesselLocation` | carte, déploiement, récupération |
| Écran ouvert et sélection locale | présentation concernée | aucune règle de gameplay |
| Réglages joueur | service de réglages | input, caméra, audio, présentation |
La profondeur affichée est calculée à partir de la position physique, puis
transmise à `DiveSession` par un échantillon de télémétrie. Le HUD ne la recalcule
jamais depuis un nœud 3D.
Le domaine n'interroge jamais une horloge. L'application fournit exactement un
`DiveStep` par tick de physique à 60 Hz. Aucun tick n'est produit pendant une
pause et aucun temps de pause n'est rattrapé. Un pas supérieur à 0,1 s est
subdivisé ou refusé.
Les observations et objets d'une plongée restent provisoires jusqu'à sa fin.
Le résultat détermine ce qui rejoint la campagne ; aucune sauvegarde ne tente de
restaurer la physique sous l'eau.
## 8. Premiers contrats typés
Les noms ci-dessous fixent les responsabilités initiales. Leur API exacte sera
validée par tests avant toute scène complète.
### `VehicleCommand`
- séquence ;
- poussée longitudinale normalisée ;
- gouvernail normalisé ;
- commande verticale normalisée ;
- forte poussée active ou non.
Produit par l'infrastructure d'entrée, validé par l'application et consommé par
l'acteur physique. La souris n'y contribue jamais.
### `CameraLookCommand`
- variation de lacet en radians ;
- variation de tangage en radians ;
- demande de recentrage éventuelle.
Ce contrat oriente seulement la caméra fixée dans la cabine. Le regard persiste,
reste borné par le hublot et ne se recentre pas automatiquement par défaut. Les
limites initiales de playtest sont environ ±30° horizontalement et -17° / +11°
verticalement. Un recentrage lent optionnel et un recentrage instantané en mode
réduction des mouvements restent des réglages de présentation.
### `VehicleTelemetry`
- position et orientation mondiales ;
- vitesse linéaire dans le monde et vitesse angulaire dans le repère du
véhicule ;
- profondeur en mètres ;
- efforts longitudinal, de gouverne et vertical normalisés ;
- forte poussée active ;
- identifiant de session et séquence.
Snapshot temporaire immuable produit par le monde. Aucune référence de nœud
n'en sort et la position du sous-marin n'est pas sauvegardée en V1.
### Entrées d'un pas de plongée
- `DiveTick` : séquence et secondes écoulées ;
- `DiveTelemetrySample` : profondeur et efforts effectifs utiles aux règles ;
- `CollisionObservation` : séquences de collision et de tick, vitesse normale
d'impact en m/s ;
- `ToolPowerDemand` : ID d'outil et intensité électrique effective ;
- `EjectionIntent` : commande active ou inactive ;
- `ReturnRouteSample` : distance, ascension et statut connu ou inconnu ;
- `DiveStep` : agrégat unique de ces entrées pour un tick.
Les collisions sont séparées de la télémétrie continue et sont idempotentes.
Le domaine possède leurs seuils, dégâts et délais de répétition. Les efforts
représentent la sortie réelle des actionneurs, jamais une touche pressée.
### `DiveSnapshot` et `DiveUpdate`
`DiveSnapshot` contient :
- `BatterySnapshot` : kWh restants et maximaux, ratio, puissance actuelle en kW
et autonomie estimée ;
- `OxygenSnapshot` : litres standards restants et maximaux, ratio, consommation
en L/min et autonomie estimée ;
- `HullSnapshot` : intégrité actuelle et maximale, ratio, pression extérieure,
certifiée, critique et d'écrasement en bar ;
- `DepthSnapshot` : profondeur actuelle, certifiée, critique et d'écrasement en
mètres ;
- `ReturnEstimate` : kWh requis, marge en kWh et ratio, statut sûr, serré,
insuffisant ou inconnu ;
- `DiveAlertState` : niveaux indépendants pour oxygène, batterie, coque et
profondeur, plus la sévérité maximale ;
- `EjectionSnapshot` : progression d'une tenue de trois secondes ;
- motif terminal éventuel : retour, éjection volontaire, oxygène épuisé ou
coque détruite.
`DiveUpdate` regroupe ce snapshot cohérent et des événements typés comme
`AlertLevelChanged`, `ResourceDepleted`, `HullDamaged` et `DiveTerminated`.
L'UI et l'audio ne redéduisent jamais les seuils. Une batterie vide est une
défaillance, mais ne termine pas instantanément la plongée.
Les niveaux d'alerte sont `NORMAL`, `ATTENTION`, `RETURN`, `CRITICAL` et
`FAILURE`. La tenue d'éjection dure trois secondes, se réinitialise au relâchement
et n'avance pas en pause. Une confirmation explicite depuis le menu produit le
même motif d'éjection volontaire sans demander une seconde tenue.
L'ordre interne d'un pas est fixe : validation, consommation, pression,
collisions ordonnées, éjection, retour et alertes, état terminal, puis
publication d'un seul `DiveUpdate`.
### `ResolvedDiveRules`
Au début d'une plongée, `DiveRulesResolver` combine dans cet ordre :
1. règles de base ;
2. capacités et améliorations du sous-marin ;
3. profil de difficulté ;
4. aides d'accessibilité de gameplay ;
5. validation et bornage.
Le résultat est immuable pour cette plongée et seul le choix des sources est
sauvegardé. Les mêmes sources donnent toujours les mêmes règles.
### `SonarSampleBuffer` et `SonarContact`
Le scan stocke en mémoire des tableaux parallèles compacts de positions,
normales, intensités, élévations, matériaux et statuts d'observation. Un même
index décrit une cellule ; ligne et colonne sont dérivées. Un accesseur typé
`sample_at(row, column)` masque cette représentation.
Le buffer devient immuable après publication. Des clusters spatiaux
déterministes produisent des `SonarContact` séparés avec ID, matériau, centre,
limites, intensité maximale et nombre d'échantillons. La couleur d'altitude est
relative au scan, mais les valeurs réelles en mètres restent stockées.
### `SonarScan`
- identifiant unique ;
- transform du capteur à l'émission ;
- portée et ouvertures ;
- durée ;
- dimensions de grille ;
- `SonarSampleBuffer`, contacts et échelle de couleur ;
- état : prêt, capture, révélation ou récupération.
Le repère est figé à l'émission, origine au capteur, +X tribord, +Y haut et +Z
avant en mètres. L'adaptateur convertit le -Z avant de Godot. La révélation dure
2,5 s, suivie de 0,35 s de récupération, sans file d'attente d'entrée. Un scan
courant et un scan précédent en fondu existent au maximum.
Deux acquisitions de production peuvent être comparées derrière le même
contrat : réécriture bathymétrique de référence du POC et faisceau frontal par
rayons. Une seule devient autoritaire après la porte de calibration.
### `SurfaceSurvey` et `SurfaceEchoArea`
Un relevé de surface contient la position du navire, son empreinte, sa séquence
et des zones d'écho avec centre approximatif et rayon d'incertitude. Rejouer le
même relevé produit le même résultat. Seules les zones sémantiques sont
sauvegardées ; elles sont remplacées par une épave connue après localisation
sous l'eau.
### `VesselLocation`
- ID de région et de repère de coordonnées ;
- position est et nord en mètres ;
- cap en radians ;
- état au port, sur site, en eau libre ou en route ;
- ID d'un mouillage connu éventuel.
La composition convertit cette donnée métier en transform Godot. Ni la carte,
ni la sauvegarde ne manipulent le nœud 3D du navire.
### `MissionProgress`
- termes visibles du contrat et objectifs réels séparés ;
- objectifs et révélations connus ;
- `WreckRecord` pour chaque épave localisée : position, identité éventuelle,
faits observés et activités connues ;
- cible présumée révisable ;
- état de l'accès et de la découpe ;
- état des objets : sur site, dans le panier, dans la cale, remis ;
- rapport final distinct du résultat de chaque plongée.
### Définitions de contenu
- `WreckDefinition` : identité, époque, dimensions, preuves et références.
- `ContractTerms` : donneur, informations visibles, objet demandé, paiement et
prérequis.
- `CampaignObjectiveDefinition` : déclencheurs réels, visibilité et révélations.
- `EvidenceDefinition` : type d'observation, cible et texte de fiche.
- `ArchivePackDefinition` : secteur, prix et fiches enrichies.
- `ItemDefinition` : volume, catégorie, valeur et caractère essentiel.
- `UpgradeDefinition` : coût, prérequis et effet typé.
- `DiveSiteDefinition` : scène, profondeur, limites et contenu autorisé.
Chaque définition possède un ID stable et ne référence jamais une ressource par
un texte libre destiné au joueur.
## 9. Flux principaux
### Contrat, archives et relevé de surface
```text
Port UI
→ consulter ContractTerms et registre public
→ acheter éventuellement ArchivePackDefinition
→ NavigateVessel met à jour VesselLocation
→ RequestSurfaceSurvey produit des SurfaceEchoArea déterministes
→ sélection d'une zone d'écho
→ StartDive résout ResolvedDiveRules et crée DiveSession
→ Composition charge le DiveSite
→ World reçoit uniquement les paramètres nécessaires
```
### Pilotage
```text
InputAdapter
→ VehicleCommand
→ PilotUseCase
→ SubmarineActor
→ VehicleTelemetry
→ DiveTelemetrySample + CollisionObservation + ToolPowerDemand
→ DiveStep à 60 Hz
→ DiveUpdate
→ cockpit et alarmes
```
### Scan sonar
```text
Action F
→ RequestSonarScan
→ validation de l'état
→ WorldSonarAdapter capture les retours
→ SonarScanService structure le scan
→ révélation 2,5 s puis récupération 0,35 s
→ SonarPresentationSnapshot
→ renderer compact et agrandi
```
La petite et la grande vue consomment la même sortie du renderer. Elles ne
maintiennent jamais deux reconstructions indépendantes.
#### Piste post-V1 : échos géologiques de surface
La V1 ne présente pas un rocher banal comme un contact prometteur : chaque
écho persistant du sonar du bateau conduit à une épave, un site secondaire
ou un élément documentable. Une itération ultérieure pourra faire renvoyer des
échos aux rochers et autres formations géologiques afin d'enrichir
l'interprétation du relevé de surface. Cette piste ne sera retenue qu'après
playtest, si ces faux positifs créent une déduction intéressante plutôt qu'une
plongée vide ou punitive.
### Observation et récupération
```text
Regard + proximité + vitesse valide
→ ObserveEvidence ajoute un fait idempotent
→ dossier compare sans conclure
→ SetSuspectedWreck reste révisable
→ CutAccess consomme cutter + stabilisation et persiste
→ RecoverItem valide la capacité puis consomme bras + stabilisation
→ DiveInventory est mis à jour à la fin du transfert
```
L'acteur d'épave ne décide pas qu'une mission est terminée. Il décrit le contact
observé ; le domaine applique les règles de campagne. Une opération suspendue
par la dérive conserve sa progression. Le cutter de référence consomme 30 kW
pendant environ 12 s et le bras 8 kW pendant environ 6 s, hors stabilisation.
Le dossier complet met les ticks en pause. Il reste aussi consultable avant la
plongée et depuis les instruments du navire.
### Retour, treuillage et transfert
```text
Sous-marin en surface à faible vitesse dans un rayon de 25 m
→ WinchSubmarine
→ résultat immuable
→ retour sur le navire sans restauration automatique
→ actions séparées RefillOxygen / RechargeBattery / EmptyBasket
→ EmptyBasket exige la place nécessaire dans la cale
→ sauvegarde atomique après chaque action
→ AnalyzeRecoveredData révèle la piste du U-Boot
→ retour au port, UnloadHold, remise, paiement et vente explicites
```
Une fin de plongée ne termine pas la mission. Le rapport final et la remise des
objets sont des actions de campagne explicites. Après perte du sous-marin, le
joueur revient sur le navire au site, doit naviguer au port et demander son
remplacement au Chantier naval.
L'analyse des données est disponible à bord dès le vidage du panier et ne
consomme ni ressource ni temps simulé. La copie reste acquise même si le module
physique est remis à l'entreprise avant sa lecture.
L'écran principal du port expose directement `Décharger la cale` et `Prendre la
mer`. Avant le départ, il récapitule batterie, oxygène, coque, panier, cale,
dossier suivi et archives possédées. Une préparation incomplète produit un
avertissement, jamais une restauration ou un blocage automatique.
## 10. Scènes de production minimales
| Scène | Responsabilité |
|---|---|
| `vertical_slice_root.tscn` | composition et transitions du parcours |
| `main_menu.tscn` | nouvelle partie, reprise, réglages et sortie |
| `pause_menu.tscn` | pause réelle et commandes de sortie de plongée |
| `settings_screen.tscn` | coque commune des quatre catégories de réglages |
| `confirmation_dialog.tscn` | confirmation sûre des actions destructrices |
| `port_screen.tscn` | entreprise nommée, Archives, Chantier, Comptoir et départ |
| `maritime_map.tscn` | position du navire, zones, relevés et sites connus |
| `vessel_service_screen.tscn` | ressources, panier, cale et analyse à bord |
| `dossier_screen.tscn` | contrat, registre, observations et cible présumée |
| `dive_site_survey_wreck.tscn` | environnement, limites et points d'injection |
| `surface_vessel_actor.tscn` | repère 3D statique, feux et zone de treuillage |
| `submarine_actor.tscn` | physique et adaptateurs du véhicule |
| `survey_wreck.tscn` | géométrie, collisions et points observables |
| `decoy_wreck.tscn` | variante modulaire extérieure et points observables |
| `cockpit_hud.tscn` | télémétrie et alertes |
| `sonar_display.tscn` | affichage compact et agrandi partagé |
| `company_screen.tscn` | termes du contrat, remise, rapport et paiement |
| `archives_screen.tscn` | registre public et pack d'archives du secteur |
| `shipyard_screen.tscn` | onglets Sous-marin et Navire, réparation et cale |
| `counter_screen.tscn` | sélection et vente manuelle de cargaison |
| `debriefing_screen.tscn` | résultat de plongée sans transfert implicite |
Ces scènes reçoivent leurs dépendances depuis la composition. Aucun autoload de
gameplay n'est introduit pour éviter cette injection.
## 11. Sauvegarde V1 minimale
La sauvegarde existe avant le métajeu complet afin d'empêcher une architecture
reposant sur des nœuds sérialisés.
La campagne narrative est unique, mais le joueur peut conserver plusieurs
sauvegardes. `Continuer` charge la sauvegarde valide la plus récente et
`Charger` affiche la liste sans supprimer les sauvegardes plus récentes.
Organisation V1 :
- trois autosauvegardes sémantiques : avant plongée, après plongée et progression
de campagne ;
- une sauvegarde technique de secours invisible pour chacune ;
- jusqu'à dix sauvegardes manuelles nommées, seulement hors plongée ;
- réglages joueur séparés de la campagne.
Le format est un JSON explicite avec enveloppe `schema_version`, `campaign_id`,
`save_id`, `created_at_utc`, `kind` et `payload`. Le payload contient au moins :
- argent, dette et difficulté choisie ;
- `VesselLocation`, disponibilité du sous-marin et ressources non remplies ;
- contrats, objectifs connus et révélations ;
- zones d'écho, épaves localisées, identités et observations sécurisées ;
- états persistants d'ouverture ;
- panier, cale, stockage et objets narratifs ;
- archives, plans et améliorations ;
- dernier résultat de plongée.
La position arbitraire du sous-marin, les particules, les collisions, les points
sonar, leurs couleurs et le maillage dynamique ne sont pas sauvegardés. Un
marqueur technique indique seulement qu'une plongée était active. Après crash ou
fermeture forcée, le jeu revient à l'état précédant la plongée sans restauration
physique ni perte automatique du véhicule.
Les dictionnaires JSON restent confinés au codec d'infrastructure ; les autres
couches reçoivent des objets typés. Procédure : sérialiser dans un fichier
temporaire, relire et valider, puis remplacer atomiquement la sauvegarde
précédente. Conserver une fixture par version, des migrations explicites et un
test de round-trip dès la première implémentation. Une version inconnue est
refusée proprement.
## 12. Stratégie de tests
### Unitaires
- tick à 60 Hz, pause sans tick et rejet ou subdivision d'un pas trop grand ;
- consommation d'oxygène, propulsion, outils et stabilisation ;
- seuils de profondeur et dégâts ;
- estimation du retour ;
- transitions terminales ;
- ordre et idempotence des collisions ;
- résolution base, améliorations, difficulté et accessibilité ;
- validation et progression temporelle d'un scan ;
- remplacement d'un seul scan précédent ;
- classification des matériaux ;
- clustering de plusieurs contacts sans moyenne globale ;
- relevé de surface identique depuis la même position et recoupement borné ;
- ajout idempotent d'une preuve ;
- hypothèse révisable sans validation implicite ;
- capacité du panier et de la cale ;
- plongée terminée distincte du rapport final ;
- perte, franchise, dette et remplacement selon la difficulté ;
- vente, remise, réparation et achat d'amélioration.
### Contrats
- IDs de contenu uniques ;
- références résolues ;
- contrat principal terminable ;
- une cible et deux leurres possèdent chacun des faits cohérents ;
- chaque leurre a au moins une contradiction découvrable ;
- objet principal invendable ou récupérable selon la règle ;
- pack d'archives facultatif et campagne terminable sans lui ;
- effet d'amélioration reconnu ;
- sauvegarde V1 aller-retour ;
- rejet d'une version inconnue ;
- textes visibles munis d'une clé de localisation.
### Intégration
- entrée abstraite vers mouvement et télémétrie ;
- souris vers caméra sans commande d'orientation du véhicule ;
- collision vers dégâts uniques ;
- sonar monde vers `SonarScan` puis maillage ;
- rotation du véhicule vers orientation de la carte ;
- vue compacte et agrandie partageant la même texture ;
- carte vers relevé de surface puis `SurfaceEchoArea` persistante ;
- observation monde vers progression de mission ;
- outil vers consommation, progression suspendue et accès persistant ;
- récupération vers panier seulement après transfert terminé ;
- surface vers treuillage sans restauration automatique ;
- actions manuelles vers ressources, cale, analyse, paiement et sauvegarde ;
- chargement d'une sauvegarde vers écran correct ;
- pause vers suspension puis reprise des ticks sans consommation intermédiaire ;
- remappage vers commande véhicule sans accès direct de la présentation ;
- réglage modifié, annulé, appliqué puis rechargé ;
- abandon confirmé vers conséquence unique, sans double application.
### Parcours automatisés
1. Relevé de surface, cible correcte parmi deux leurres, récupération et
treuillage.
2. Retour sans vider le panier puis replongée : ressources et cargaison restent
inchangées.
3. Vidage du panier, analyse du module, remise et déblocage de la piste U-Boot.
4. Mauvaise hypothèse révisée sous l'eau sans message de validation.
5. Abandon volontaire : données conservées, panier perdu, navire encore sur le
site et remplacement seulement au port.
6. Perte en Standard puis Expert : modèle basique et franchises 500 € / 750 €.
7. Batterie vide : pas de mort instantanée, oxygène continue.
8. Sauvegarde après actions manuelles puis redémarrage.
9. Marqueur de plongée active simulé : reprise avant plongée sans perte.
Les parcours utilisent des adaptateurs déterministes, pas une simulation de
plusieurs minutes en temps réel.
### Tests humains
- compréhension du pilotage sans aide orale ;
- lecture du relief dans les deux tailles sonar ;
- découverte de l'accès ;
- compréhension des indices ;
- anticipation du retour ;
- désir de relancer une mission.
Chaque session note les interventions verbales du testeur. Une réussite obtenue
après explication ne satisfait pas le critère d'autonomie.
## 13. Budgets techniques initiaux
Valeurs de gameplay de départ, toutes configurables et soumises au playtest :
| Valeur | Cible initiale |
|---|---:|
| Fréquence de simulation | 60 Hz |
| Batterie basique | 100 kWh |
| Oxygène Standard | environ 16 min |
| Autonomie Standard | environ 1,2 km |
| Intégrité basique | 100 points |
| Panier | 6 unités |
| Cale initiale / première amélioration | 12 / 18 unités |
| Cutter | 30 kW, environ 12 s, 0,10 kWh hors stabilisation |
| Bras | 8 kW, environ 6 s, 0,013 kWh hors stabilisation |
| Examen d'un indice | environ 1,5 s à 8–12 m |
| Récupération par le navire | rayon 25 m, faible vitesse |
| Sonar de surface | portée 400 m, incertitude 150 / 75 / minimum 50 m |
| Argent initial / archives / contrat | 500 € / 500 € / 1 000 € |
| Cale 12 vers 18 / objet secondaire | 750 € / environ 200 € |
| Réparation | 4 € par point d'intégrité |
Multiplicateurs de difficulté :
| Règle | Exploration | Standard | Expert |
|---|---:|---:|---:|
| Oxygène | ×0,75 | ×1 | ×1,20 |
| Batterie | ×0,80 | ×1 | ×1,15 |
| Collision | ×0,65 | ×1 | ×1,25 |
| Pression | ×0,50 | ×1 | ×1,35 |
| Grâce avant rupture | ×1,50 | ×1 | ×0,75 |
| Franchise | 0 € | 500 € | 750 € |
Budgets d'exécution :
| Budget | Cible de départ |
|---|---:|
| Framerate de validation locale | 60 FPS à 1080p |
| Budget total par frame | 16,7 ms |
| Sonar, coût CPU moyen pendant scan | ≤ 3 ms |
| Sonar, pic CPU exceptionnel | ≤ 8 ms sur une frame |
| Durée de chargement du site sur SSD | ≤ 3 s |
| Écriture de sauvegarde | ≤ 100 ms hors blocage visible prolongé |
| Barrière qualité locale | ≤ 60 s avant croissance du contenu |
| Erreurs ou avertissements Godot acceptés | 0 |
Ces budgets sont des alarmes, pas des promesses commerciales. Une mesure doit
indiquer la machine, le renderer, la résolution, le build et la scène.
Forward+ est l'unique renderer de production conformément à
`docs/adr/0004-forward-plus-only.md`. Ses réglages de qualité et son coût sont
testés immédiatement sur les machines disponibles ; cette validation ne doit
pas attendre la phase de finition graphique.
## 14. Tranches d'implémentation
### Tranche 0 — fondations exécutables
État au 10 août 2026 : implémentée. La production démarre sur un menu principal
minimal, puis `Nouvelle partie` ouvre l'écran de diagnostic alimenté par
`DiveSession`. `Continuer` reste désactivé tant que la persistance n'existe pas
et l'écran complet de réglages appartient à une tranche ultérieure.
- Créer les sous-dossiers nécessaires, sans architecture vide exhaustive.
- Définir IDs, `DiveTick`, `DiveStep`, `ResolvedDiveRules`, snapshots et
événements.
- Créer `DiveSession` comme règle pure, sans horloge interne, avec tests à 60 Hz.
- Créer une composition minimale, un menu principal fonctionnel et un écran de
diagnostic.
Sortie : état de plongée déterministe, testable sans scène, affiché par une scène
de production qui ne dépend pas des POC.
### Tranche 1 — véhicule de production
État au 10 août 2026 : implémentée. `Nouvelle partie` ouvre désormais un
parcours court en vue intérieure avec mouvement inertiel, caméra souris séparée,
ressources réelles, environnement Forward+, pause complète et remappage clavier
avec détection puis permutation des conflits. Les valeurs de départ reprennent
la baseline du POC A sans importer son code.
- Réécrire le contrôleur derrière `VehicleCommand` et `VehicleTelemetry`.
- Reproduire les sensations validées du POC A à partir de sa baseline.
- Intégrer caméra intérieure, hublot et `CameraLookCommand` indépendant de la
coque.
- Ajouter le menu pause et le premier parcours de remappage.
- Ajouter les tests de mouvement et de dégâts prioritaires.
Sortie : parcours de pilotage court avec ressources et retour immédiat lisible.
### Tranche 1.5 — cockpit fonctionnel représentatif
État au 16 août 2026 : implémentée après revue visuelle native Forward+ à
1280 × 720. Cette tranche corrige le graybox initial, qui ne contenait qu'une
caméra, un cercle Canvas et des textes superposés.
- Construire une coque intérieure 3D fixe par rapport au véhicule, indépendante
du regard de la caméra.
- Remplacer le cercle Canvas par un hublot 3D occultant avec cadre, joint, verre,
boulons et cloisons.
- Ajouter tableau de bord, consoles, leviers, bouton d'éjection, éclairage et
premiers matériaux métalliques procéduraux.
- Présenter batterie, oxygène, coque, pression, profondeur, vitesse et retour
sur des instruments physiques alimentés par `DiveUpdate` et
`VehicleTelemetry`.
- Réserver un moniteur physique au sonar de la tranche 2.
- Limiter la surimpression 2D aux alertes, à l'éjection et à la fin de plongée.
- Garantir un relief et une balise visibles dès le point de départ.
Les textures détaillées, l'usure, les animations secondaires et l'art final
restent dans la tranche 6. Le cockpit actuel doit cependant rester assez
représentatif pour valider la composition du sonar et la lisibilité en jeu.
Sortie : un habitacle identifiable et fonctionnel, dont les instruments
constituent la cible réelle d'intégration du sonar.
### Tranche 2 — sonar de production
- Définir `SonarSampleBuffer`, `SonarContact` et `SonarScan`.
- Séparer acquisition, reconstruction et présentation.
- Réécrire la bathymétrie validée sans importer le POC B et comparer le
faisceau frontal derrière le même contrat.
- Mesurer le coût et passer à une mise à jour incrémentale.
Sortie : relief inconnu révélé manuellement, lisible dans les deux vues, avec
rotation et remplacement d'un relevé.
### Tranche 3 — site et découverte
- Ajouter carte limitée, position persistante du navire et sonar de surface.
- Construire le terrain graybox, l'épave majeure contemporaine et deux leurres
extérieurs modulaires.
- Ajouter registre, pack d'archives, faits observables et dossier comparatif.
- Implémenter les états cartographiques sans révéler un secret inconnu.
- Organiser le premier playtest de recherche.
Sortie : 8 testeurs sur 10 passent de la zone probable à la bonne épave et
peuvent expliquer leur choix, ou une porte de décision est déclenchée.
### Tranche 4 — interaction et retour
- Ajouter cutter, stabilisation assistée, consommation électrique et ouverture
persistante.
- Ajouter bras, panier de 6 unités, module, pièce et objet secondaire.
- Ajouter navire 3D simplifié, zone de retour, treuillage, abandon et perte.
- Automatiser les parcours nominaux et d'échec.
Sortie : boucle de plongée complète sans métajeu.
### Tranche 5 — contrat, économie et sauvegarde
- Ajouter port, entreprise, Archives, Chantier naval et Comptoir.
- Ajouter entretien manuel, cale, analyse des données, remise, vente, dette et
amélioration 12 vers 18.
- Ajouter contrat visible, objectif réel et révélation de la piste U-Boot.
- Ajouter Continuer, les états de chargement et la persistance des réglages.
- Écrire les sauvegardes JSON V1 et leurs tests de contrat.
Sortie : boucle verticale complète et rejouable après redémarrage.
### Tranche 6 — présentation et validation
- Remplacer les éléments graybox nécessaires à la compréhension.
- Ajouter audio moteur, sonar, alarmes et ambiance.
- Ajouter réglages d'accessibilité retenus.
- Profiler, tester sur trois OS et conduire le playtest final.
Sortie : décision documentée de poursuivre, corriger ou réduire le projet.
## 15. Risques et portes de décision
| Risque | Détection précoce | Réponse prévue |
|---|---|---|
| Sensations perdues pendant la réécriture | test véhicule dès tranche 1 | comparer aux mesures POC A, ajuster avant sonar |
| Sonar lisible seul mais confus en mission | playtest tranche 3 | réduire relief parasite ou resserrer la zone probable |
| Sonar de surface répétitif | nombre de relevés avant une plongée utile | conserver les résultats déterministes et réduire la zone initiale |
| Leurres aussi coûteux que la cible | mesure de production des micro-sites | extérieurs modulaires, faits seulement, aucun accès complexe |
| Ouverture impossible à représenter | site graybox dédié | ajouter surfaces locales ; ne pas revenir aux voxels globaux |
| Stabilisation d'outil frustrante | taux d'interruption et corrections requises | élargir les tolérances, suspendre sans réinitialiser |
| États dupliqués entre monde et HUD | tests de propriétaire et snapshots | supprimer la copie, rétablir un flux unidirectionnel |
| Scènes fortement couplées | contrôle d'architecture | déplacer l'assemblage vers `composition` |
| Sauvegarde conçue trop tard | Save V1 tranche 5 au plus tard | bloquer le métajeu tant que le round-trip échoue |
| Contenu lent à produire | mesure sur l'épave contemporaine | réduire preuves et interactions avant d'ajouter une épave |
| Performance du maillage sonar | profil tranche 2 | buffers incrémentaux, fréquence bornée ou travail distribué |
| Palette inaccessible | tests contraste/daltonisme | palette alternative et indices de forme |
| Portée verticale excessive | revue à chaque tranche | retirer une fonctionnalité de coût comparable |
Une porte de décision produit une conclusion écrite. Elle ne devient pas une
suite indéfinie de corrections sans critère de sortie.
## 16. Décisions à formaliser après validation de ce cadrage
Une fois ce document approuvé, créer des ADR séparés pour :
1. le renderer Forward+ unique de production, formalisé dans
`docs/adr/0004-forward-plus-only.md` ;
2. les contrats de tick, télémétrie, snapshot/événements et règles résolues,
formalisés dans `docs/adr/0005-fixed-dive-ticks-and-typed-updates.md` ;
3. le contrat sonar commun, le buffer compact et la porte de comparaison,
formalisés dans `docs/adr/0006-sonar-contract-and-acquisition-gate.md`, puis
l'acquisition retenue dans un ADR de sélection ;
4. la sauvegarde JSON V1, ses emplacements, migrations, secours et remplacement
récupérable, formalisés dans `docs/adr/0007-versioned-json-saves.md` ;
5. l'absence d'autoload de gameplay et la propriété des services par la
composition, formalisées dans
`docs/adr/0008-composition-owned-service-lifetimes.md` ;
6. le modèle de progression qui sépare vérité du contenu, termes du contrat,
objectifs réels et connaissances du joueur, formalisé dans
`docs/adr/0009-player-knowledge-driven-progression.md` ;
7. la limitation de la V1 à une surface bathymétrique unique, formalisée dans
`docs/adr/0010-single-surface-bathymetry-for-v1.md` ; un modèle hybride
nécessitera un prototype et un nouvel ADR lorsqu'un site concret l'exigera.
Les noms de classes peuvent évoluer pendant la tranche 0. Les responsabilités,
les propriétaires et les directions de dépendance ne changent qu'avec un ADR.
## 17. Première action après approbation
La première implémentation ne sera ni le sous-marin ni le sonar. Elle créera une
tranche verticale minuscule :
1. `DiveSession` pur recevant un `DiveStep` explicite ;
2. `ResolvedDiveRules` produit depuis des fixtures de base et de difficulté ;
3. `VehicleTelemetry` minimal fourni par un faux adaptateur ;
4. `DiveUpdate` affiché dans une scène de diagnostic ;
5. tests de tick, consommation, profondeur, alertes et état terminal ;
6. ajout de cette suite à `scripts/quality_gate.sh`.
Cette tranche prouvera le chemin complet domaine → application → présentation
et la discipline de tests avant de porter un comportement complexe.