Environment pipeline
How the 4×4 km Amber Basin is generated and dressed — deterministic heightmap from world.json, roads and zone masks, splat materials, modular kits, vegetation, lighting per area, streaming, walkability for server + client, and tests.
The world is built from data, deterministically, so an agent can regenerate, diff and test it.
world.json (zones, centres, bounds, moods) is the input. Seeded generators produce terrain, roads and masks, and
hand-authored kits and set-dressing go on top.
◆Area direction before generation
Write the area brief before the stages: combat/escape space, sightlines,
landmarks, materials, lighting/fog, vegetation/life, sound, camera clearance, streaming and budgets. Version the complete
seed/generator/input/override set; regeneration preserves authored landmarks. Validate movement-gem routes and both
cameras as well as bot walking; inspect telegraphs on bright salt, dark ash and water at Low. New camp slope tuning is
proposed in development-standards.json; it is not the world's walkability slope limit. Gameplay hazards/destruction
need separate authoritative contracts before adoption.
◆Stages
| # | Stage | How (agent) | Output | Test |
|---|---|---|---|---|
| 1 | Macro layout | tools/world/layout.mjs reads world.json, places zone parcels, the road graph (town → 1 → … → 10, Arena spur), the river, cliffs | tools/world/out/layout.json + preview PNG | roads connect all areas; road slope ≤ 12°; parcels don't overlap |
| 2 | Heightmap | seeded noise (fBm + ridged for Stormquill) + hydraulic erosion lite + carve roads/river + flatten town/arena plateaus | 16-bit 4097² PNG | determinism (same seed → same hash); slope stats per zone; no spikes |
| 3 | Masks & splats | rules: slope → rock, height → dunes, distance-to-water → reed/grass, zone overrides (salt, ash, kiln) | 4 splat layers per chunk + zone masks | every pixel's weights sum to 1; per-chunk ≤ 4 layers |
| 4 | Walkability grid | 1 m grid from slope (≤ 38°), water depth, cliffs and blocker meshes; jump links for Cairn Vault logs/ledges | bitset + jump-link list, shared with the server (zoen-sim) | bot walks town → every area; no unreachable spawn; jump links valid |
| 5 | Chunking | 256 m chunks, LOD 129² / 65² / 33² with skirts, meshopt compressed | 256 chunk files | chunk size 0.5–2 MB; seams crack-free (edge test) |
| 6 | Kits | modular Amber Gate architecture (walls, gates, towers, stalls, adobe houses) from ART-ENV-054 → Blender (blockout → model → bake → LOD) | .glb kit pieces | tri/texture budgets; pivots on grid (0.5 m); collision proxies |
| 7 | Set-dressing | rule-based scatter (rocks, palms, reeds, crates, carts, bones) per biome + hand-placed hero props | instance lists per chunk | density budget; nothing on roads; no floating props (raycast test) |
| 8 | Vegetation | instanced palms/reeds/grass with wind vertex shader + impostors beyond 80 m | instance buffers | draw calls per chunk ≤ budget |
| 9 | Lighting & mood | four keyframes per area (dawn, day, dusk, night) on one sun + IBL; per-area fog/grade from mood over every phase; weather profiles from time-weather.json; baked AO for kits | lighting presets per phase + weather profiles | captures across the review matrix match the mood; no blown highlights; telegraph contrast passes in every state on Low |
| 10 | Streaming | 2-ring prefetch around the player, priority by camera direction; budgeted uploads per frame | streamer | hitch < 8 ms p99 while riding at 10.5 m/s |
| 11 | Audio beds | one bed per area plus one spot emitter on its landmark (kiln roar, canal water, forge…); environment-only ordinary outdoor travel/combat; engaged named boss themes are permitted (ADR-026) | audio map | ambience changes within 5 s of crossing a boundary |
◆Biomes
| Area | Ground | Hero props | Mood |
|---|---|---|---|
| Amber Gate | sandstone pavers, packed sand | twin-roof gate, bell tower, stalls | golden afternoon, lanterns |
| Dewgrass Meadow | short grass, dew terraces | wicker bridges, fallen training log | soft morning haze |
| Old Orchard | orchard soil, fallen fruit | amber trees, toll sheds | dappled sun |
| Reedwater Banks | mud, shallow water, reeds | three-arch canal bridge | teal reflections |
| Clay Cut | ochre clay terraces | quarry crane, canal locks | harsh ochre |
| Cinder Kilns | grey ash, brick | kilns + chimneys, ember pits | red glow, smoke shafts |
| Saltway Flats | white salt crust, puddles | causeways, windbreaks | glare |
| Bellshade Court | flagstones, sand | shrine steps, silent bells, pillars | violet dusk |
| Stormquill Ridge | wind-cut rock | copper relay posts, roosts | overcast, lightning |
| Ashroot Grove | ash, green roots | black cedars, the lost caravan | ash haze |
| Jade Seal Ruins | cracked jade stone | courts, sealed western gate | cold jade rim light |
| Caravan Crown Arena | packed earth ring | caravan-wheel yard | dust-storm red |
◆Time of day and weather
In from day one (ADR-030). time-weather.json holds the four phases, the five weather
states, the weather each area allows, each area's signature phase and the budgets. Look and sound only; the server owns
the clock. An area keeps its mood as a grade and fog profile over every phase, and the 12 story-camera captures are
taken at the area's signature phase. Rules for authoring and review: development guide.
◆Making it feel wide (Silkroad scale)
- Long sightlines: far terrain LOD + impostor skyline (distant cliffs, cities on the horizon) and a sky dome with sun haze.
- Travel rhythm: 30–60 s of quiet road between areas, landmarks visible from far away (bell tower, kiln smoke, relay towers).
- Caravan life on roads: NPC caravans walking set routes (cheap instanced crowds, no AI), dust devils, birds.
◆Tests and evidence
Generators run in CI with fixed seeds (hash test). Bots walk the road graph. A fixed set of 12 story-camera
screenshots (one per area) is captured after every environment task, so progress compares like for like. Captures
go in logs/evidence/world/<area>/<UTC>.png.
Source: zoen/docs/production/ENVIRONMENT.md · 1,041 words · edit the Markdown, not this page.
