# Formes de relief variées — Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Extend the bake tool with polyline canyons, noise-edged outcrops, boulder fields, polyline escarpments and a strata modifier, then bake a `terrain_showcase` site that demonstrates all five reference landforms and is covered by geometric contract tests. **Architecture:** `tools/site_terrain_baker.gd` gains a `Modifier` phase (after the primitive sum, with the local gradient) and a per-primitive material override hook. New primitives are nested classes next to the existing ones. A new recipe `tools/sites/terrain_showcase_recipe.gd` and its baked `content/sites/terrain_showcase*.{tres,res}` are the demonstration site. Nothing under `game/` changes. **Tech Stack:** Godot 4.7.2 headless, GDScript, `bash scripts/quality_gate.sh`. **Spec:** `docs/briefs/terrain-varied-landforms.md`. ## Global Constraints - Godot binary (Git Bash): `export GODOT_BIN="/c/Users/olivi/Downloads/Godot_v4.7.2-stable_win64.exe/Godot_v4.7.2-stable_win64_console.exe"`; ripgrep: `export PATH="$PATH:/c/Users/olivi/AppData/Local/Programs/Microsoft VS Code/resources/app/node_modules/@vscode/ripgrep/bin"`. - `tools/` depends on `game/domain/` only; nothing under `game/` or `content/` references `res://tools/` (architecture check). - Determinism: every random element is a seeded `FastNoiseLite` or `RandomNumberGenerator`; the same recipe bakes byte-identical arrays. - `content/sites/zone1_vigilant_terrain.res` must not change (re-bake and `git diff --stat` empty for it). - Test runners: `TEST_COUNT` equals the number of `_expect` calls. - Never hand-edit `.tres`/`.res`. - Commits end with `Co-Authored-By: Claude Fable 5.1 `. ## Tasks ### Task 1: Modifier phase and per-primitive material hook - `Primitive.material_at(x, z) -> int` returning `NO_MATERIAL := -1`. - `Modifier.modify(x, z, elevation, gradient: Vector2) -> float`. - `Recipe.modifiers: Array[Modifier]`. - `bake()` order: sum → modifiers (gradient by central differences on the current array) → floor → slope material → primitive material → patches. - Unit tests: a modifier that adds 1 m everywhere shifts the field; a primitive forcing ROCK on a flat plane wins over the slope rule; zone 1 recipe bakes identical to the checked-in `.res`. ### Task 2: `Canyon` and `Escarpment` (polyline primitives) - Shared static `distance_to_path(point, path) -> float`, `arc_position(point, path) -> Vector2(along_m, total_m)` and `signed_distance_to_path` (sign from the nearest segment's cross product, positive on the right of travel). - Edge noise: `FastNoiseLite` seeded, `TYPE_SIMPLEX_SMOOTH`, frequency 0.05, amplitude `edge_amplitude_m`. - Tests: Canyon depth on the flat floor, zero far away, follows a corner, closes over one half-width at the ends; Escarpment right side lower by `drop_m`, left side unchanged. ### Task 3: `Outcrop` and `BoulderField` - Outcrop: `e = (sqrt((dx/rx)² + (dz/rz)²) - 1) * mean_radius + noise`, `delta = height * (1 - smoothstep(-wall_width, 0, e))`, rock where `delta > 0.3 * height` and `rock_top`. - BoulderField: `RandomNumberGenerator` seeded; disc sampling `r = radius * sqrt(u)`, angle `TAU * v`; per boulder `h = r_b * height_ratio`, profile `h * sqrt(max(0, 1 - (d / r_b)²))`; combine by `maxf`; early reject outside `radius + max_r`; rock where profile > 0. - Tests: plateau height, rock on top, zero at two radii; boulder field deterministic, zero outside, rock on a boulder, two overlapping boulders do not sum. ### Task 4: `Strata` modifier - Formula from the brief §4.3. Tests: a 45° plane with 2 m layers and sharpness 0.9 produces at least two flat runs (|gradient| < 0.1) on a transect; a flat plane is unchanged; sharpness 0 is identity. ### Task 5: `terrain_showcase` recipe, bake, registry - Recipe per brief §5; `bake_site_terrain.gd` RECIPES gains `terrain_showcase`; bake; preview PNG under `docs/briefs/captures/`. - Verify zone 1 re-bake identical. ### Task 6: Contract and integration tests for the showcase - `tests/contract/run_site_content_tests.gd`: new `_test_showcase_content()` per brief §6. - `tests/integration/run_site_terrain_integration.gd`: showcase loads < 3 s, canyon ray lower than mesa ray, scan reads rock and sand. - Foundation test: `select_dive_site` on the showcase is not required. ### Task 7: Docs - ADR 0012 amendment, `content/README.md`, `tests/README.md`, technical plan status line, brief status. - Full gate green.