Files
Ransom-s-wake/docs/adr/0012-authored-heightfield-dive-sites.md
T
OlivierandClaude Opus 5.5 dbd207ef1b build(gate): forbid production code from importing authoring tools
The architecture check scans tools/ for duplicate class names and fails
when game/ or content/ references res://tools/. The three tools scripts
drop their global class_name (every caller preloads them), and ADR 0012
records that tools/ depends on the domain only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:57:00 +02:00

71 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# 0012 — Sites de plongée en champ de hauteur authoré
- Statut : accepté
- Date : 2026-10-06
- 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.
## 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.