322 lines
18 KiB
Markdown
322 lines
18 KiB
Markdown
# Proposition — terrain du site de la zone I : « Banc du Vigilant »
|
||
|
||
**Statut : validé par Olivier le 2026-10-06** (plan de masse, objet secondaire à 62 m, pipeline par script de cuisson, nom « Banc du Vigilant » conservé). Sert de spécification de référence pour l'implémentation.
|
||
|
||
Rédigée le 2026-10-06 à partir de `docs/GAME_DESIGN_PLAN.md`,
|
||
`docs/VERTICAL_SLICE_TECHNICAL_PLAN.md`, `docs/POC_B_TECHNICAL_BASELINE.md`,
|
||
des ADR 0004, 0006, 0008, 0010 et du code sous `game/world/`. Rien n'a été
|
||
exécuté ; aucun fichier de jeu n'est modifié par ce brief.
|
||
|
||
---
|
||
|
||
## 1. Objectif
|
||
|
||
Donner au premier site de plongée (navire de prospection, zone I, 35 m) un
|
||
terrain statique, crédible et porteur de gameplay : le relief doit cacher
|
||
l'épave, se lire au sonar, offrir une route sûre et une route risquée, et
|
||
rendre la recherche intéressante sans marqueur. C'est la pièce « terrain
|
||
graybox » de la tranche 3 du plan technique.
|
||
|
||
Terminé quand :
|
||
|
||
- un joueur sans aide trouve l'accès à l'épave cible en 5 à 10 minutes après
|
||
l'arrivée dans la zone (critère §5 du plan technique) ;
|
||
- les deux routes existent, se distinguent au sonar et se justifient par les
|
||
ressources (profondeur, batterie, collisions) ;
|
||
- le sonar renvoie roche, sable et métal selon la cellule touchée, pas un seul
|
||
matériau pour tout le fond ;
|
||
- l'environnement de test du véhicule utilise la même implémentation de terrain
|
||
que le site (une seule implémentation par concept) ;
|
||
- `bash scripts/quality_gate.sh` passe.
|
||
|
||
## 2. Ce qui existe et ce qui contraint
|
||
|
||
| Élément | État | Conséquence pour le terrain |
|
||
|---|---|---|
|
||
| `game/world/sites/vehicle_test_environment.gd` | heightmap analytique 61×69, 180×200 m, -40 à -78 m, `HeightMapShape3D` | graybox de test ; devient un client du nouvel acteur terrain |
|
||
| `game/world/sonar/reference_bathymetry_acquisition.gd` | rayons verticaux, lit `sonar_material` / `sonar_reflectivity` sur le collider | le sonar suit tout terrain qui a une collision ; matériau par corps, pas par cellule |
|
||
| ADR 0010 | surface unique en V1 | pas de grotte, tunnel ni surplomb porteur d'information |
|
||
| Plan technique §3 | terrain conçu à la main, route sûre + route risquée | pas de génération procédurale à l'exécution |
|
||
| Plan technique §13 | chargement du site ≤ 3 s, 60 FPS 1080p | taille et découpage du maillage bornés |
|
||
| ADR 0010 | les limites de zone ne sont pas un relief à interpréter | la frontière jouable est une règle applicative, pas un mur de terrain |
|
||
| GDP §18 | low-poly atmosphérique, textures simples, identité par lumière et brouillard | réalisme = formes et lumière crédibles, pas photoréalisme |
|
||
| GDP §4.1 | coque I certifiée 60 m ; 100–115 % = dégâts croissants | une route ou un objet entre 60 et 69 m est un risque lisible, pas une mort |
|
||
| GDP §7.1 | zone d'écho de surface : 150 m, puis 75 m, minimum 50 m | le joueur arrive à ≤ 75 m de l'épave ; la portée sonar est 95 m |
|
||
| GDP §13.2 | une cible récente, deux leurres légers inscrits au registre | trois sites d'épave sur un seul terrain |
|
||
|
||
**Point à vérifier avant de bâtir dessus** (non vérifié à l'exécution) : dans
|
||
`vehicle_test_environment.gd`, le maillage visuel place la ligne 0 à z = +28
|
||
(proche) alors que `HeightMapShape3D` place la ligne 0 au z local le plus
|
||
négatif. Si c'est confirmé, la collision actuelle est le terrain visuel
|
||
retourné avant/arrière, et le sonar scanne la collision, pas le maillage. Les
|
||
tests d'intégration ne le détecteraient pas (ils comptent des échantillons,
|
||
pas une forme). Le nouvel acteur terrain doit avoir un test qui compare
|
||
hauteur visuelle et hauteur de collision en quelques points.
|
||
|
||
## 3. Partis pris de réalisme
|
||
|
||
Le site est une **plate-forme carbonatée de bordure de plateau** caraïbe,
|
||
l'environnement réel le plus courant à 25–45 m dans l'arc antillais :
|
||
|
||
- **Plateau** à 22–32 m : dalle de calcaire corallien recouverte de sable
|
||
biogène, patch reefs isolés, rides de sable orientées par la houle.
|
||
- **Système d'éperons et sillons** (« spur and groove ») sur la bordure
|
||
externe : crêtes rocheuses parallèles séparées de couloirs de sable de 8 à
|
||
20 m de large, descendant vers la rupture de pente. C'est la forme la plus
|
||
lisible au sonar et la plus naturelle pour créer des couloirs de navigation.
|
||
- **Rupture de pente** à 42–48 m puis **tombant** jusqu'à 85 m, avec un
|
||
**cône d'éboulis** au pied des sillons.
|
||
- **Sédimentation** : un navire échoué sur une pente de sable biogène
|
||
s'enfonce et se recouvre partiellement en quelques mois ; les objets lourds
|
||
glissent vers le bas de la pente. Les deux phénomènes servent le gameplay.
|
||
|
||
Ce qui reste hors réalisme volontairement : pas de corail animé, pas de
|
||
végétation dense, pas de courant (V0.5), pas de houle. Les formes, la lumière
|
||
décroissante avec la profondeur, le brouillard et les particules portent la
|
||
crédibilité, conformément à la direction artistique.
|
||
|
||
## 4. Le site
|
||
|
||
### 4.1 Dimensions
|
||
|
||
| Donnée | Valeur proposée |
|
||
|---|---:|
|
||
| Zone jouable | 600 × 600 m |
|
||
| Terrain physique | 768 × 768 m (marge de 84 m de chaque côté, noyée dans le brouillard) |
|
||
| Champ de hauteur | 513 × 513 cellules, 1,5 m par cellule, élévations float32 (`SiteTerrainData`) |
|
||
| Profondeur min / max du terrain | 20 m / 88 m |
|
||
| Profondeur d'écrasement coque I | hors terrain : le fond ne tue jamais par lui-même |
|
||
| Mouillage du navire | centre nord du plateau, 24 m de fond |
|
||
| Point de départ du sous-marin | sous le navire, 10 m de profondeur |
|
||
|
||
Les distances sont dimensionnées pour l'autonomie Standard (environ 1,2 km,
|
||
16 minutes d'oxygène) : aucune épave à plus de 320 m du mouillage, aucune
|
||
paire d'épaves à plus de 260 m l'une de l'autre.
|
||
|
||
### 4.2 Plan de masse (nord en haut, navire au centre nord)
|
||
|
||
```text
|
||
N
|
||
+---------------------------+ 20 m plateau clair, sable + patch reefs
|
||
| [Navire] |
|
||
| Rides . . | 26 m [B] leurre 1 : voilier de plaisance
|
||
| ~ ~ ~ [B] | posé à plat sur le sable, visible
|
||
| ~ ~ ~ ~ |
|
||
| les Deux ^^ l'Échine | 28 m crête longue nord-sud = fil d'Ariane
|
||
| Frères ^^ |||| |
|
||
| |||| |
|
||
| la Saignée |||| | 40 m [C] leurre 2 : caboteur acier dans
|
||
| \\\\\\ || [C] | un patch reef, échos roche + métal
|
||
| \\\\\\ || |
|
||
| \\\\\\ ====== | 45 m rupture de pente (ligne continue)
|
||
| \\\\\ [A] | 35 m [A] CIBLE : navire de prospection
|
||
| ----- .. . | dans un sillon, poupe sur la rupture
|
||
| tombant . . . | 50-64 traîne de débris descendant la pente
|
||
| ======== . | 62 m objet secondaire, légèrement
|
||
| 85 m | sous la profondeur certifiée
|
||
+---------------------------+
|
||
S
|
||
```
|
||
|
||
Noms de travail : **l'Échine** (crête de 6 m de haut), **les Deux Frères**
|
||
(deux pitons jumeaux de 6 m de haut), **les Rides** (champ de rides de
|
||
sable), **la Saignée** (sillon principal), **le Tombant**.
|
||
|
||
### 4.3 Les trois épaves et leur terrain
|
||
|
||
**[A] Cible — navire de prospection (35 m).** Couché dans le sillon de la
|
||
Saignée, à 15 m de la rupture de pente. Coque enfoncée d'un tiers dans le
|
||
sable (GDP §7.6, « coque enterrée dans le sédiment ») : au sonar, elle se lit
|
||
comme une bosse allongée métallique dans un couloir, pas comme une silhouette
|
||
évidente. La poupe dépasse au-dessus de la rupture ; le portique, un conteneur
|
||
et une partie du gréement ont glissé en contrebas et forment une **traîne de
|
||
débris** de 50 à 64 m le long du tombant. La traîne est un fil conducteur :
|
||
un joueur qui descend trop tôt sur le tombant la rencontre et peut la
|
||
remonter jusqu'à la coque. Caché par : la bosse de l'Échine à l'est, la
|
||
profondeur du sillon, le sédiment.
|
||
|
||
**[B] Leurre 1 — voilier de plaisance (26 m).** Posé à plat sur le sable, en
|
||
plein plateau, au bord des Rides. Facile à trouver, visible de loin. Bois et
|
||
résine : écho faible, aucun métal massif. Il apprend au joueur à lire une
|
||
silhouette et une matière au sonar. Contradiction découvrable : pas de
|
||
portique, un seul mât, taille moitié moindre.
|
||
|
||
**[C] Leurre 2 — caboteur en acier (40 m).** Encastré dans un patch reef sur
|
||
le flanc est de l'Échine. Même ordre de taille que la cible, même matériau :
|
||
le vrai piège. Les échos roche et métal se mêlent ; il faut contourner et
|
||
scanner deux fois pour isoler le contact. Contradictions : immatriculation
|
||
différente, deux hélices au lieu d'une, pas de portique, avarie qui ne
|
||
correspond pas au rapport.
|
||
|
||
### 4.4 Les deux routes vers la cible
|
||
|
||
**Route sûre — par l'Échine (≈ 470 m, 26–32 m).** Depuis le navire, suivre la
|
||
crête longue vers le sud. Elle est lumineuse, large, sans obstacle, et se lit
|
||
d'un seul scan. Elle mène au bord du plateau au-dessus de la Saignée : il
|
||
faut ensuite descendre dans le sillon par son extrémité nord, à faible
|
||
pente. Coût : temps et batterie. Récompense : zéro dégât, retour facile à
|
||
estimer.
|
||
|
||
**Route risquée — par la Saignée (≈ 370 m, 36–48 m).** Un sillon de 12 à
|
||
18 m de large, aux parois de 8 à 10 m, qui coupe le plateau en diagonale et
|
||
débouche directement sur la proue de la cible. Sombre (les projecteurs
|
||
deviennent nécessaires), étroit (collisions), en pente (la batterie de
|
||
remontée compte). Au sonar : une dépression continue, lisible comme une
|
||
« ouverture possible » (GDP §7.2, point 4). Aucune paroi ne surplombe, donc
|
||
compatible ADR 0010. Récompense : trajet plus court et direct sur la proue.
|
||
|
||
**Le tombant — la tentation (50–64 m).** Pas une route : une pente qui
|
||
descend sous la rupture. L'objet secondaire (1 unité, ~200 €) repose à 62 m,
|
||
dans la zone 100–107 % de la profondeur certifiée : craquements, dégâts lents,
|
||
alerte claire. Le joueur voit la traîne de débris descendre et doit décider
|
||
de s'arrêter. C'est le « site légèrement sous la profondeur certifiée » de
|
||
GDP §7.6 appliqué à un objet optionnel, jamais à la cible.
|
||
|
||
### 4.5 Repères pour naviguer sans GPS
|
||
|
||
Le joueur n'a ni carte locale ni marqueur. Le terrain doit donc fournir des
|
||
amers reconnaissables au sonar à 95 m :
|
||
|
||
| Amer | Forme sonar | Rôle |
|
||
|---|---|---|
|
||
| l'Échine | crête longue de 6 m de haut, orientée nord-sud | fil d'Ariane entre le navire et la cible |
|
||
| les Deux Frères | deux pitons jumeaux, 6 m de haut, 20 m d'écart | repère ouest unique, sert à se recaler |
|
||
| les Rides | ondulations régulières de 1 m | signe « plateau nord, navire proche » |
|
||
| la Saignée | sillon rectiligne, bords nets | entrée de la route risquée |
|
||
| la rupture de pente | ligne continue de rupture | « ne pas dépasser » et limite sud |
|
||
|
||
Chaque amer est unique sur le site : aucune forme n'est répétée ailleurs,
|
||
pour que la reconnaissance ne trompe pas.
|
||
|
||
## 5. Ce que le terrain apporte au gameplay
|
||
|
||
1. **Chercher avant de récupérer** (pilier GDP §1.4) : la cible n'est ni la
|
||
plus visible [B] ni la plus « métallique » [C] ; elle est la plus cachée.
|
||
L'écho de surface amène à ≤ 75 m, le sillon et le sédiment font le reste.
|
||
2. **Lecture du sonar comme compétence** : rides = plateau, crête = route,
|
||
dépression = passage, bosse dans un couloir = chose enfouie. Le site
|
||
enseigne un vocabulaire que les sites suivants réutiliseront.
|
||
3. **Risque prévisible** : chaque danger s'annonce avant de coûter. Le sillon
|
||
est visiblement étroit, la pente visiblement longue, l'objet à 62 m
|
||
visiblement sous la ligne de rupture.
|
||
4. **Décision de retour** : la route risquée à l'aller et l'Échine au retour
|
||
est le plan « malin » ; le terrain rend ce raisonnement possible.
|
||
5. **Enquête matérielle** : la traîne de débris raconte le naufrage (impact
|
||
sur la rupture, glissement, enfouissement) et concorde avec le rapport de
|
||
la société, ce que les leurres ne font pas.
|
||
6. **Rejouabilité** : revenir au site après identification (GDP §8, « repère
|
||
local ») pour récupérer l'objet secondaire est une mini-expédition avec un
|
||
seul but : gérer la profondeur.
|
||
|
||
## 6. Sonar et matériaux par cellule
|
||
|
||
Aujourd'hui le matériau sonar est une meta par corps. Le site a besoin de
|
||
roche, sable et métal selon l'endroit touché :
|
||
|
||
- un **champ d'octets de matériaux** (un octet par cellule : roche ou sable,
|
||
déduit de la pente à la cuisson puis corrigé par des `MaterialPatch` nommés
|
||
dans la recette) est stocké dans le `SiteTerrainData` à côté des
|
||
élévations ;
|
||
- l'acteur terrain expose `sonar_material_at(world_position)` et
|
||
`sonar_reflectivity_at(world_position)` ; l'acquisition les appelle quand
|
||
le collider les possède, sinon lit la meta comme aujourd'hui ;
|
||
- réflectivités de départ : roche 0,72 (valeur actuelle), sable 0,45, métal
|
||
1,0. Les valeurs vivent dans la définition de site, pas dans le code.
|
||
|
||
Les épaves restent des corps distincts avec leur propre meta ; le clustering
|
||
de contacts existant les sépare du fond.
|
||
|
||
## 7. Rendu
|
||
|
||
- Un seul matériau terrain, shader Forward+ : mélange **triplanaire** sable /
|
||
roche piloté par la pente (sable sous 25°, roche au-dessus de 40°, fondu
|
||
entre), normal map de rides sur le sable, teinte assombrie avec la
|
||
profondeur pour suivre la palette GDP §18.2 (vert clair à 25 m, bleu froid
|
||
à 45 m, indigo au pied du tombant).
|
||
- Maillage découpé en **64 tuiles de 96 × 96 m** (64 × 64 cellules), avec
|
||
`visibility_range` pour ne dessiner que les tuiles dans le brouillard
|
||
utile ; une seule `HeightMapShape3D` pour la collision.
|
||
- Props low-poly posés à la main, en nombre borné : blocs d'éboulis au pied
|
||
du tombant, têtes de corail sur les patch reefs, rien d'animé.
|
||
- Brouillard, lumière directionnelle et particules de la scène de test
|
||
actuelle sont conservés et réglés par site.
|
||
|
||
## 8. Architecture proposée
|
||
|
||
| Couche | Élément | Responsabilité |
|
||
|---|---|---|
|
||
| `game/domain/sites/` | `DiveSiteDefinition` (Resource typée) | identifiant, nom affiché, `SiteTerrainData`, limites jouables, position et cap de départ, placements (épaves, leurres, objet secondaire, débris), routes de contrôle |
|
||
| `game/domain/sites/` | `TerrainHeightField` (RefCounted pur) | lecture de hauteur et de matériau à une position, conversion monde ↔ cellule, bornes ; testable sans scène |
|
||
| `game/application/sites/` | `PlayableBoundsRule` | « hors zone » comme résultat typé depuis la télémétrie ; émet un avertissement, jamais un mur |
|
||
| `game/world/sites/` | `BathymetricTerrainActor` | construit tuiles, collision et matériau depuis la définition ; expose matériau sonar par position |
|
||
| `game/world/sites/` | `dive_site_zone1.tscn` | scène du site : terrain, environnement, points d'injection pour épaves et navire |
|
||
| `game/composition/` | câblage | charge la définition, instancie le site, injecte la règle de bornes |
|
||
| `content/sites/` | `zone1_vigilant.tres` + `zone1_vigilant_terrain.res` | données du site |
|
||
| `tools/` (hors runtime) | script de cuisson | produit le `.res` depuis une description de primitives géomorphologiques ; déterministe, versionné, jamais appelé par le jeu |
|
||
|
||
Les conventions du contrat : hauteur en mètres négatifs vers le bas, +X est,
|
||
-Z nord (convention Godot, convertie une seule fois dans
|
||
`TerrainHeightField`). Le terrain est stocké en `SiteTerrainData` au format
|
||
`.res` (élévations en float32 et matériaux en octets) produit par la recette
|
||
de cuisson ; le PNG 16 bits est écarté (ADR 0012). Ces points sont formalisés
|
||
dans l'**ADR 0012 — terrain de site en champ de hauteur authoré**, requis par
|
||
les guardrails §5 et §11 (nouveau contrat de données persistant dans le
|
||
dépôt).
|
||
|
||
`vehicle_test_environment.gd` perd sa formule analytique : la formule devient
|
||
le premier cas d'usage du script de cuisson, et la scène de test charge une
|
||
petite définition de site (fixture) comme le ferait le vrai site.
|
||
|
||
## 9. Pipeline d'auteur
|
||
|
||
1. **Graybox cuit** (cette tranche) : une description déclarative des
|
||
primitives (plateau, crête, pitons, sillon, rupture, tombant, rides)
|
||
dans le script de cuisson. Itération en minutes, diff lisible, aucun outil
|
||
externe. C'est « conçu à la main » : chaque forme est placée et nommée.
|
||
2. **Passe de sculpture** (tranche 6) : export de la heightmap vers Blender,
|
||
retouche manuelle, réimport. Le contrat ne change pas.
|
||
3. **Jamais** de génération à l'exécution ni de dépendance à un plugin
|
||
terrain ; si un plugin devenait souhaitable, ADR d'abord.
|
||
|
||
## 10. Tests
|
||
|
||
- **Unitaires** : `TerrainHeightField` (interpolation bilinéaire, bornes,
|
||
conversion monde ↔ cellule, matériau par cellule) ; `PlayableBoundsRule`.
|
||
- **Acteur** : hauteur de collision égale à la hauteur du champ en plusieurs
|
||
points, dont les quatre coins (ferme le doute du §2).
|
||
- **Contrats** sur `zone1_vigilant.tres` : trois placements d'épave dans les
|
||
limites ; cible et objets requis au-dessus de 60 m ; objet secondaire entre
|
||
60 et 69 m ; les amers listés sont uniques (pas deux crêtes de même
|
||
signature) ; les deux routes existent sous forme de chemins de contrôle
|
||
(liste de points) dont chaque point respecte sa profondeur annoncée et
|
||
n'est pas dans la roche.
|
||
- **Intégration** : charger le site, lancer un scan de référence depuis la
|
||
position de départ et vérifier roche et sable dans le buffer ; un rayon
|
||
vers le sillon touche le terrain ; temps de chargement sous 3 s.
|
||
- **Humains** (playtest tranche 3) : 8/10 trouvent l'accès en 5–10 min ; les
|
||
testeurs nomment spontanément au moins un amer.
|
||
|
||
## 11. Ordre de construction
|
||
|
||
1. ADR 0012, `DiveSiteDefinition`, `TerrainHeightField` et leurs tests.
|
||
2. `BathymetricTerrainActor` avec tuiles, collision et matériau sonar par
|
||
position ; migration de l'environnement de test sur une fixture.
|
||
3. Script de cuisson et première cuisson du Banc du Vigilant (graybox) ;
|
||
bornes jouables ; scène `dive_site_zone1.tscn`.
|
||
4. Shader triplanaire et props bornés.
|
||
5. Points d'injection pour les trois épaves et le navire (les épaves
|
||
elles-mêmes appartiennent au reste de la tranche 3).
|
||
|
||
Chaque étape laisse la barrière verte et la scène jouable.
|
||
|
||
## 12. Décisions demandées à Olivier
|
||
|
||
1. **Validation du plan de masse** (§4.2–4.4) : trois épaves, deux routes, un
|
||
tombant tentateur. Variante possible : déplacer le leurre 2 dans la Saignée
|
||
pour piéger la route risquée.
|
||
2. **Objet secondaire à 62 m** : garder la tentation sous la profondeur
|
||
certifiée, ou le remonter à 55 m pour un premier site plus doux ?
|
||
3. **Pipeline** : script de cuisson d'abord (recommandé) ou sculpture Blender
|
||
dès le graybox ?
|
||
4. **Nom** : « Banc du Vigilant » ou autre.
|