# 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) | | Heightmap | 512 × 512 px, 1,5 m par cellule, 16 bits | | 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 **masque de matériaux** 512 × 512 (R = roche, G = sable, B = réservé débris/concrétion) accompagne la heightmap ; - 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 heightmap 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.