Files
Ransom-s-wake/docs/briefs/terrain-varied-landforms.md
T

10 KiB
Raw Blame History

Proposition — formes de relief variées pour les sites de plongée

Statut : exécuté en autonomie le 2026-10-06 sur demande d'Olivier (« implémente ce genre de terrains variés, terrain statique, ne te concentre que sur le terrain, pas les effets de rendu ou la végétation »). Les décisions ouvertes sont listées en §8.

Rédigée à partir de cinq photos de référence fournies par Olivier, de l'ADR 0012, de tools/site_terrain_baker.gd et du brief docs/briefs/terrain-site-zone1-gameplay.md.


1. Objectif

Étendre le vocabulaire de formes du script de cuisson pour que les sites suivants (U-Boot « sous falaise », navire océanographique « dans un canyon », GDP §15) puissent être authorés avec le même pipeline que le Banc du Vigilant : canyons à parois raides et strates, crevasses étroites, éperons et chaos de blocs, buttes rocheuses, falaises sinueuses. Terrain statique, surface unique (ADR 0010), aucun changement de rendu ni de végétation.

Terminé quand :

  • chaque forme des cinq références a une primitive nommée, testée unitairement, dans tools/site_terrain_baker.gd ;
  • un site de démonstration cuit (content/sites/terrain_showcase.tres) montre les cinq formes côte à côte, se charge en moins de 3 s et passe des tests de contrat géométriques (profondeur, pente, largeur, matériau) ;
  • le Banc du Vigilant est cuit à l'identique (aucun octet de zone1_vigilant_terrain.res ne change) ;
  • bash scripts/quality_gate.sh passe.

2. Lecture des références

Photo Ce qu'on voit Forme de relief Ce qu'un champ de hauteur peut en garder
1 Deux masses rocheuses alvéolées encadrant un chenal de sable grossier éperons rocheux + chenal deux buttes aux bords irréguliers, chenal plat entre elles, rugosité forte sur la roche
2 Fente très étroite et profonde entre deux parois quasi verticales crevasse sillon de 5–6 m de large, 20 m de profondeur, parois à 80°+ ; pas de surplomb
3 Pente de mamelons rocheux arrondis mamelons buttes à flancs doux sur une pente, rugosité moyenne
4 Canyon aux parois verticales stratifiées, fond de sable plat ridé, mesas en haut canyon à strates tranchée à fond plat, parois raides quantifiées en gradins horizontaux, rides sur le fond, plateaux sommitaux
5 Platier : têtes de corail et blocs épars sur sable ridé chaos de blocs champ de demi-ellipsoïdes de 2–6 m de rayon, matériau roche, sable ridé entre

Hors périmètre, volontairement : lumière, caustiques, couleur de l'eau, herbier, corail (rendu et végétation).

3. Ce qui existe et ce qui manque

Le cuiseur additionne des primitives elevation_delta(x, z) puis déduit le matériau de la pente (roche au-dessus de 20°) et applique des MaterialPatch circulaires. Les primitives actuelles (SlopedPlane, Blob, Ridge, Groove, Step, Ripples, Roughness) sont toutes lisses (gaussiennes ou smoothstep) et mono-segment. Il manque :

  1. des tracés en polyligne (canyon, crevasse, falaise sinueuse) ;
  2. des bords irréguliers (bruit de contour) pour casser l'aspect « gaussien » ;
  3. des formes à sommet plat et flancs raides (butte, mesa) ;
  4. des champs d'objets discrets combinés par maximum, pas par somme (blocs qui ne fusionnent pas en bosse) ;
  5. une phase de modification après la somme, qui connaît la pente locale, pour quantifier les parois en strates ;
  6. un matériau imposé par une primitive (un bloc est roche même sur son sommet plat).

4. Décision : extension du cuiseur

4.1 Contrat

  • Primitive.elevation_delta(x_m, z_m) -> float : inchangé, additif.
  • Primitive.material_at(x_m, z_m) -> int : nouveau, renvoie NO_MATERIAL (-1) par défaut ; une valeur SonarMaterial.Value l'emporte sur la règle de pente, dans l'ordre des primitives, avant les MaterialPatch.
  • Modifier.modify(x_m, z_m, elevation_m, gradient) -> float : nouvelle phase. gradient est la pente locale Vector2(dE/dx, dE/dz) calculée par différences centrées sur le champ courant ; les modificateurs s'enchaînent dans l'ordre de Recipe.modifiers, après la somme et avant le plancher.
  • Ordre de cuisson : somme des primitives → modificateurs → plancher floor_elevation_m → matériau par pente → matériau par primitive → MaterialPatch.

4.2 Nouvelles primitives

Primitive Paramètres Forme
Canyon path: PackedVector2Array, half_width_m, depth_m, wall_softness_m, edge_seed, edge_amplitude_m tranchée à fond plat le long d'une polyligne ; parois smoothstep sur wall_softness_m ; distance au tracé perturbée par un bruit de contour ; se referme sur une demi-largeur à chaque bout
Outcrop centre, radius_x_m, radius_z_m, height_m, wall_width_m, edge_seed, edge_amplitude_m, rock_top butte elliptique à sommet plat, flanc de largeur wall_width_m, contour perturbé ; matériau roche partout où elle dépasse 30 % de sa hauteur si rock_top
BoulderField centre, radius_m, seed, count, boulder_radius_min_m, boulder_radius_max_m, height_ratio count demi-ellipsoïdes tirés par RandomNumberGenerator seedé dans le disque, combinés par maximum ; roche sur toute leur emprise
Escarpment path: PackedVector2Array, drop_m, softness_m, slope_beyond, edge_seed, edge_amplitude_m Step le long d'une polyligne : le terrain descend à droite du sens de parcours ; ligne de crête perturbée par un bruit de contour

4.3 Nouveau modificateur

Modificateur Paramètres Effet
Strata layer_height_m, sharpness (0–1), minimum_slope_degrees, full_slope_degrees, centre, radius_m (0 = partout) quantifie l'élévation en gradins de layer_height_m là où la pente dépasse minimum_slope_degrees (plein effet à full_slope_degrees) ; sharpness 0 = aucun effet, 1 = marches franches ; le fond plat et le plateau ne bougent pas

Formule : f = frac(e / h), f' = clamp((f - 0.5) / (1 - s) + 0.5, 0, 1), e' = lerp(e, floor(e / h) * h + h * f', w) avec w = smoothstep(tan(min), tan(full), |gradient|) * masque.

4.4 Ce qui ne change pas

Le contrat de données (SiteTerrainData, ADR 0012 §2), l'acteur de monde, la collision, le sonar, le shader. Les .res restent les artefacts dérivés ; la recette reste le document d'auteur. Le bruit de contour est un FastNoiseLite seedé, donc déterministe.

5. Site de démonstration : terrain_showcase

But : prouver chaque forme en jeu et au sonar, servir de catalogue pour l'auteur des sites suivants. Pas un site de mission : un seul placement (balise de mouillage), aucune épave, aucune route.

Donnée Valeur
Champ 513 × 513 cellules, 1,0 m, origine (-256, -256)
Zone jouable 440 × 440 m centrée
Plateau de base 30 m, incliné de 4 m vers le sud
Profondeur min / max 18 m / 80 m
Départ (0, -12, 0), cap nord

Plan de masse (nord en haut) :

   +---------------------------------------------+
   |  NW : canyon à strates        NE : crevasse |
   |  mesa à -24 m, tranchée       fente 6 m de  |
   |  28 m de large au sommet,     large, 20 m   |
   |  20 m de profond, parois à    de profond,   |
   |  55°, gradins 4 m, fond ridé  entre buttes  |
   |                 [départ]                    |
   |  SW : chaos de blocs          SE : éperons  |
   |  80 blocs r 2–6 m sur         deux buttes   |
   |  sable ridé                   alvéolées,    |
   |                               chenal 20 m   |
   |  ====== falaise sinueuse (Escarpment) ===== |
   |  tombant vers -80 m, mamelons sur la pente  |
   +---------------------------------------------+

6. Tests

  • Unitaires (run_site_baker_tests.gd) : Canyon (fond plat à la profondeur demandée, nul hors tracé, suit le coude d'une polyligne, fermeture aux bouts) ; Outcrop (sommet à height_m, roche sur le sommet si rock_top, nul à deux rayons) ; BoulderField (déterministe, nul hors disque, roche sur un bloc, maximum et non somme) ; Escarpment (côté droit plus bas, drop égal à drop_m) ; Strata (une pente raide devient des gradins : au moins deux niveaux plats ; un fond plat ne bouge pas) ; cuisson du Banc du Vigilant identique à l'artefact versionné.
  • Contrat (run_site_content_tests.gd, section showcase) : canyon (profondeur ≥ 20 m sous la mesa, fond plat à ± 1 m sur 10 m, paroi ≥ 60° quelque part sur une transversale, ≥ 2 replats de gradin) ; crevasse (fond ≥ 16 m sous les bords, largeur au fond ≤ 8 m) ; chaos (roche sur un bloc, sable entre deux blocs, ≥ 40 cellules de roche distinctes… mesuré par fraction de roche dans le disque) ; éperons (chenal plus bas que les deux buttes, roche sur chaque butte) ; falaise (drop ≥ 20 m entre deux points de part et d'autre) ; bornes et profondeurs globales.
  • Intégration (run_site_terrain_integration.gd) : chargement du showcase sous 3 s, rayon dans le canyon plus bas que sur la mesa, scan de référence lisant roche et sable.

7. Documentation

  • ADR 0012 : amendement §3 (liste des primitives, phase de modification, matériau par primitive), sans changer le contrat de données.
  • content/README.md, tests/README.md : le site de démonstration.
  • Captures : PNG de prévisualisation du showcase sous docs/briefs/captures/.

8. Décisions laissées à Olivier

  1. Résolution : le showcase est cuit à 1,0 m par cellule (crevasse de 6 m lisible). Les gradins imposent une paroi d'au moins 2 à 3 cellules par couche : à 1 m par cellule, des couches de 4 m sur une paroi à 55° ; une paroi à 76° (première cuisson) ne montrait aucun gradin. Les sites de mission restent à 1,5 m sauf décision contraire ; une crevasse de 5 m à 1,5 m par cellule n'a que trois cellules de large.
  2. Strates partout ? Le modificateur est appliqué au canyon seulement. L'appliquer à la falaise sud du Banc du Vigilant est un changement de recette, donc de .res, donc une re-cuisson à valider.
  3. Sites de mission suivants (U-Boot sous falaise, océanographique en canyon) : les primitives sont prêtes ; le plan de masse de chaque site reste à proposer et valider séparément.