Skip to content

Commit 9435a66

Browse files
committed
docs: record narrow-edge terrain scene research
1 parent 9b419a4 commit 9435a66

8 files changed

Lines changed: 3428 additions & 13 deletions

docs/plans/2026-07-26-alpine-hoodoos-terrain-scenes.md

Lines changed: 1332 additions & 0 deletions
Large diffs are not rendered by default.

docs/plans/2026-07-26-slot-canyon-cave-mouth-terrain-scenes.md

Lines changed: 1590 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Alpine and Hoodoos Terrain Scene Spike
2+
3+
## Status
4+
5+
**Completed (2026-07-26).** Both `alpine` and `hoodoos` were cut after three failed 4% visual reviews. The shipping change retains only `dunes`, `mesa`, `badlands`, and `glacier`. Cut reasons and work-verify receipt IDs are recorded in `implementation-notes.md`.
6+
7+
## Goal
8+
9+
Test two additions to Cloche's procedural terrain family:
10+
11+
- `alpine`: layered angular mountain ridges with sparse snow highlights.
12+
- `hoodoos`: irregular clusters of capped rock spires with a continuous bedrock floor.
13+
14+
Only scenes that remain legible around a centered screenshot at finished-card padding width will ship.
15+
16+
## Why these two
17+
18+
The screenshot covers the center of a finished card and leaves roughly 4% of the backdrop visible on each side. Both candidates can carry their identifying structure through the outer bands:
19+
20+
- Alpine ridges form continuous silhouettes across the canvas. The existing dune horizon, badlands face lighting, and glacier highlights provide most of the required rendering vocabulary.
21+
- Hoodoos form recognizable capped spires and layered protrusions. The implementation can reuse mesa cap and shoulder ideas plus badlands strata, but must avoid an evenly spaced fence.
22+
23+
Reference material:
24+
25+
- [Bryce Canyon hoodoo geology](https://www.nps.gov/brca/learn/nature/hoodoos.htm)
26+
- [USGS description of alpine glacial peaks, cirques, and arêtes](https://pubs.usgs.gov/bul/1467a-d/report.pdf)
27+
28+
## Alternatives considered
29+
30+
### Alpine plus hoodoos
31+
32+
Recommended and approved. The pair adds one broad continuous silhouette and one sparse vertical silhouette, giving the spike two meaningfully different visual tests.
33+
34+
### Alpine plus canyon
35+
36+
Lower risk to render, but a canyon's identifying negative space would sit beneath the centered screenshot. The visible side strips could read as generic strata.
37+
38+
### Basalt columns or salt flats
39+
40+
Cut from this spike. Basalt columns risk repeating the badlands fence failure and overlapping the pattern family. Salt polygons would be confined mostly to the bottom strip and could read as a geometric motif rather than terrain.
41+
42+
## Existing contract
43+
44+
Terrain palettes own color and `TerrainKind` owns structure. Every accepted scene must work with all four existing terrain palettes:
45+
46+
- `dunes`
47+
- `mesa`
48+
- `badlands`
49+
- `glacier`
50+
51+
The style seed controls every free parameter and must reproduce the same pixels. Rendering remains hand-rolled on the existing `image` and `rand` dependencies.
52+
53+
## Design
54+
55+
### Alpine
56+
57+
Generate three full-width ridge profiles:
58+
59+
1. A low-contrast far ridge near the horizon.
60+
2. A mid ridge with larger angular peaks.
61+
3. A darker near ridge that reaches both outer padding bands.
62+
63+
Each profile combines a small set of seeded peak anchors with low-amplitude warped noise. Piecewise slopes keep the skyline mountainous rather than cloud-like. Adjacent profiles use different salts and vertical ranges so they do not collapse into one band.
64+
65+
Face shading follows the local silhouette slope. Snow appears only near sufficiently high crests and on the lit side, using the palette highlight color. Snow is a sparse accent, not a white horizontal cap.
66+
67+
### Hoodoos
68+
69+
Generate two edge-anchored clusters with an optional smaller center cluster. Each cluster contains a few seeded spires with:
70+
71+
- a tapered shaft.
72+
- an irregular resistant cap wider than the shaft.
73+
- two or three horizontal erosion bands.
74+
- small width and height differences between neighbors.
75+
76+
A low continuous bedrock profile connects the scene across the bottom. Spires must overlap or vary enough that their gaps and widths do not form a repeating picket pattern. The two outer clusters are mandatory because the center is normally hidden.
77+
78+
Lighting darkens one shaft face and lifts cap rims. Strata use the horizon color at low opacity.
79+
80+
## Code boundaries
81+
82+
Primary implementation stays in `src/terrain.rs`:
83+
84+
- add `Alpine` and `Hoodoos` to `TerrainKind`.
85+
- add both public names to `TerrainKind::NAMES` and `from_name`.
86+
- add generation ranges for horizon, coverage, feature scale, and light.
87+
- add isolated profile helpers and structure painters for each scene.
88+
- route the new variants through `base_layer` and `apply_structure`.
89+
90+
Existing public surfaces already derive terrain choices from `TerrainKind::NAMES`, so no separate CLI, MCP, config, or Studio enumeration should be introduced.
91+
92+
If either scene is accepted:
93+
94+
- update the terrain documentation in `README.md`.
95+
- record the visual tradeoffs and iteration count in `implementation-notes.md`.
96+
97+
No new dependency, palette, command, configuration field, or rendering family is in scope.
98+
99+
## Data flow
100+
101+
1. `PresentationStyle` supplies the palette, style seed, and optional pinned terrain.
102+
2. `Terrain::generate` derives scene parameters once from the salted seed.
103+
3. `base_layer` paints the shared sky and ground ramps.
104+
4. A scene-specific profile supplies the local horizon where required.
105+
5. A scene-specific structure painter adds faces, strata, snow, or caps.
106+
6. Shared grain and quantization produce the final opaque pixels.
107+
108+
Profile helpers remain pure functions so silhouette behavior can be tested without image comparison.
109+
110+
## Automated acceptance
111+
112+
Tests are written before implementation and observed failing.
113+
114+
Shared requirements:
115+
116+
- both names parse and appear in `TerrainKind::NAMES`.
117+
- rendering is deterministic and seed-sensitive.
118+
- zero-width and zero-height rendering remains safe.
119+
- every outer edge band and corner contains variation.
120+
- existing dunes, mesa, badlands, and glacier tests remain unchanged and green.
121+
122+
Alpine profile requirements:
123+
124+
- relief reaches both outer bands at 440×300.
125+
- the near and middle ridges differ by at least 0.025 canvas height at 25% or more of sampled positions.
126+
- adjacent samples cannot contain single-column cliffs.
127+
- snow covers 1% to 12% of the ground pixels and never appears below the scene's elevation threshold.
128+
129+
Hoodoo profile requirements:
130+
131+
- the first and last 12.5% of the canvas each contain a spire rising at least 0.05 canvas height above bedrock.
132+
- shaft widths exceed one pixel at 440×300.
133+
- visible spire-center gaps vary by at least 0.04 canvas width between the smallest and largest gap.
134+
- the bedrock profile stays at least 0.04 canvas height across the width.
135+
- every cap is at least 1.25 times its shaft width.
136+
137+
## Visual acceptance
138+
139+
Render full backdrops and finished cards for:
140+
141+
- scenes: `alpine`, `hoodoos`.
142+
- palettes: all four terrain palettes.
143+
- seeds: 1, 7, 42, and 99.
144+
- review size: 440×300.
145+
146+
For each scene, inspect all 16 combinations for:
147+
148+
- recognition from the visible side, top, and bottom strips.
149+
- no dependence on a centered subject.
150+
- no flat outer band.
151+
- no fence, barcode, smoke, or generic noise reading.
152+
- enough contrast behind both light and dark screenshots.
153+
- clear distinction from the existing four terrain scenes.
154+
155+
Allow at most three implementation-and-render iterations per scene. An iteration means one code adjustment followed by the full 16-render visual sheet. If a scene still fails after its third sheet, remove that scene and its tests from the shipping change, record why, and continue with any scene that passed.
156+
157+
## Verification and delivery
158+
159+
After the last tracked edit, run:
160+
161+
```bash
162+
brigade work verify run --target . --command "./scripts/verify" --capture brigade-work
163+
```
164+
165+
An accepted change must have:
166+
167+
- the full verification entrypoint green.
168+
- accepted visual sheets for every retained scene.
169+
- no ignored tests, lint allowances, debug output, or new dependency.
170+
- a memory handoff recording durable profile and visual-QA lessons.

0 commit comments

Comments
 (0)