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>
71 lines
3.8 KiB
Markdown
71 lines
3.8 KiB
Markdown
# 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.
|