Strata now take a world rectangle, so the 4 m ledges cover the whole break and talus south of z = 118 m without touching la Saignée or the landmarks. Roughness gains octave and fractal-type parameters; a SlopeRoughness modifier roughens rock faces only. Both sites are re-baked with hummocks from 250 m down to 5 m. The secondary item, the first debris piece and one safe-route waypoint move a few metres to keep their contracts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
100 lines
5.4 KiB
Markdown
100 lines
5.4 KiB
Markdown
# 0012 — Sites de plongée en champ de hauteur authoré
|
||
|
||
- Statut : accepté
|
||
- Date : 2026-10-06
|
||
- Amendé : 2026-10-06 (vocabulaire de formes, voir « Amendement 1 »)
|
||
- Remplace : aucun
|
||
|
||
## Contexte
|
||
|
||
Le seul terrain de production est une formule analytique codée dans
|
||
`vehicle_test_environment.gd`. La tranche 3 exige un site conçu à la main,
|
||
lisible au sonar (ADR 0010 : surface unique), avec une route sûre et une route
|
||
risquée, et le sonar a besoin de distinguer roche et sable par cellule, pas par
|
||
corps. Il faut un contrat de données pour le terrain, son stockage dans le
|
||
dépôt et sa production.
|
||
|
||
## Décision
|
||
|
||
1. Un site de plongée est décrit par une ressource typée `DiveSiteDefinition`
|
||
(`game/domain/sites/`) : identifiant, terrain, limites jouables, point de
|
||
départ, placements d'objets et routes de contrôle.
|
||
2. Le terrain est un champ de hauteur à surface unique `SiteTerrainData` :
|
||
grille régulière de `columns × rows` cellules de `cell_size_m` mètres,
|
||
élévations en mètres (axe Y monde, négatif sous la surface) dans un
|
||
`PackedFloat32Array`, matériau sonar par cellule dans un `PackedByteArray`
|
||
(`SonarMaterial.Value`, ROCK ou SAND). Repère : +X est, +Z sud, +Y haut ;
|
||
la colonne croît avec +X, la ligne avec +Z ; la cellule `(0, 0)` est à
|
||
`(origin_x_m, origin_z_m)`.
|
||
3. Les données sont cuites hors exécution par `tools/bake_site_terrain.gd` à
|
||
partir d'une recette déclarative de primitives géomorphologiques nommées
|
||
(plateau, crête, piton, sillon, rupture de pente, rides, rugosité
|
||
déterministe par graine). La recette est le document d'auteur versionné ;
|
||
le résultat est écrit en `.res` binaire sous `content/sites/`. Le jeu ne
|
||
génère jamais de terrain à l'exécution. `tools/` dépend du domaine
|
||
(`game/domain/`) et de rien d'autre ; aucun code sous `game/` ou `content/`
|
||
ne dépend de `tools/`, ce que la barrière d'architecture vérifie.
|
||
4. Un PNG 16 bits n'est pas utilisé pour les hauteurs : le chargeur d'images
|
||
de Godot ramène les PNG 16 bits en 8 bits, soit des marches de 0,27 m sur
|
||
68 m de dénivelé. Un PNG 8 bits de prévisualisation est produit pour la
|
||
revue humaine seulement.
|
||
5. Un seul acteur de monde, `BathymetricTerrainActor`, construit le maillage
|
||
visuel et la `HeightMapShape3D` depuis le même champ ; un test compare les
|
||
deux. Il expose `sonar_material_at(position)` et
|
||
`sonar_reflectivity_at(position)` que l'acquisition sonar privilégie sur
|
||
les métadonnées de corps.
|
||
6. Les limites de la zone jouable sont une règle applicative
|
||
(`PlayableBoundsRule`) qui produit un avertissement ; elles ne sont jamais
|
||
un mur de terrain (ADR 0010).
|
||
|
||
## Conséquences
|
||
|
||
- L'environnement de test du véhicule devient une définition de site cuite,
|
||
sans formule analytique dans `game/`.
|
||
- Toute modification de terrain passe par la recette puis une cuisson ; les
|
||
fichiers `.res` sont des artefacts dérivés mais versionnés pour que le
|
||
chargement du site reste sous 3 s et que le jeu n'ait pas besoin de l'outil.
|
||
- Les tests de contrat de contenu peuvent vérifier profondeur, position et
|
||
dégagement des placements contre le champ de hauteur réel.
|
||
- Une sculpture manuelle (Blender) ultérieure devra ré-exporter vers le même
|
||
`SiteTerrainData` ; le contrat ne change pas.
|
||
|
||
## Amendement 1 — vocabulaire de formes (2026-10-06)
|
||
|
||
Le point 3 est précisé sans changer le contrat de données. La recette est une
|
||
somme de **primitives** additives, suivie de **modificateurs** qui reçoivent la
|
||
pente locale du champ en cours, puis du plancher, de la règle de matériau par
|
||
pente, des matériaux imposés par primitive et des `MaterialPatch`.
|
||
|
||
- Primitives lisses : plan incliné, bosse gaussienne, crête, sillon, rupture
|
||
de pente, rides, rugosité déterministe.
|
||
- Primitives de relief marqué : `Canyon` (tranchée à fond plat le long d'une
|
||
polyligne, contour bruité), `Escarpment` (rupture de pente le long d'une
|
||
polyligne, le terrain descend à droite du sens de parcours), `Outcrop`
|
||
(butte ou fosse à sommet plat, contour bruité, matériau roche imposé),
|
||
`BoulderField` (blocs semi-ellipsoïdaux tirés par graine, combinés par
|
||
maximum, roche imposée).
|
||
- Modificateurs : `Strata` quantifie les pentes raides en gradins horizontaux
|
||
dans un rectangle monde, les fonds et sommets plats ne bougent pas ;
|
||
`SlopeRoughness` ajoute un bruit à crêtes pondéré par la pente (roche
|
||
éraillée, sable lisse). `Roughness` accepte un nombre d'octaves et un type
|
||
fractal pour donner du relief de fond à plusieurs échelles.
|
||
|
||
Tout aléa passe par une graine explicite (`FastNoiseLite`,
|
||
`RandomNumberGenerator`) ; `tests/unit/run_site_baker_tests.gd` vérifie que
|
||
le Banc du Vigilant se recuit à l'identique. Le site de démonstration
|
||
`content/sites/terrain_showcase.tres` (« Jardin des Formes ») sert de
|
||
catalogue et de banc d'essai des contrats géométriques
|
||
(`docs/briefs/terrain-varied-landforms.md`).
|
||
|
||
## Alternatives considérées
|
||
|
||
- **Plugin de terrain externe** : rejeté, dépendance et ADR supplémentaires
|
||
sans besoin démontré ; une heightmap tuilée suffit à la V1.
|
||
- **Génération à l'exécution depuis la recette** : rejeté, le plan impose un
|
||
site conçu à la main et un chargement borné ; la cuisson garantit un
|
||
artefact figé et revu.
|
||
- **Heightmap PNG 16 bits** : rejeté pour la raison de précision ci-dessus.
|
||
- **Maillage sculpté sans champ de hauteur** : rejeté, le sonar et les tests
|
||
ont besoin d'une requête de hauteur et de matériau par position.
|