docs: curve v4 — TCRV modulation extension, TerrainCurve v4 default (terrain-water task 08)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
4d2e024b2f
commit
68f7bca8e0
2 changed files with 10 additions and 8 deletions
|
|
@ -55,7 +55,7 @@ Every section: `[u32 tag][u64 payload-length in bytes][payload]`.
|
|||
| `HGTS` / `0x53544748` | `MapSize²` × `f32` height, **X outer / Y inner** | Mandatory. The second index is the map's north/south axis; the server consumes it as world **Z**. (This axis convention was never written down for v1 — it is now normative.) Length must equal `4·MapSize²`. |
|
||||
| `BIOM` / `0x4D4F4942` | `MapSize²` × `u8` biome ordinal, same pixel order | Mandatory. Ordinals from `Enums.cs::Biome` — **append-only, never reorder** (the ordinal IS the wire value). Writer refuses ordinals > 255; reader rejects ordinals ≥ the known biome count (parse-time validation; the palette's runtime Dirt fallback for in-memory values is unchanged). Length must equal `MapSize²`. |
|
||||
| `TOWN` / `0x4E574F54` | `i32 count`, then per town: `f32 X` · `f32 Y` · `u8 tier` · `u8 isHighwayNode` (0/1) | Tier ordinals from `Enums.cs::TownTier`, append-only, range-checked on read. The highway-node flag is what the generator's road topology was built from (v1 dropped it); carried and exposed on the parsed blueprint, consumed by nothing server-side yet. |
|
||||
| `TCRV` / `0x56524354` | 50 B: `u16 curveVersion` · `f32 knot1..knot4` · `f32 spikeMax` · `f32 sea` · `f32 orangeCeil` · `f32 redCeil` · `f32 benchLo` · `f32 benchHi` · `f32 peakCap` · `f32 tailSlope` | Optional — present iff the height-redistribution curve shaped this blueprint's `HGTS` (config `TerrainCurve: "v3"`); absent = raw legacy profile. **The `u16 curveVersion` selects the field semantics and the unserialized anchor set:** v1 — knots t1..t4, spikeMax = pooled calibration max, benchLo/Hi = the 50 m plateau's lo/hi. v2 — as v1 but spikeMax = the seed's effective raw pre-curve maximum (per-seed spike normalizer). **v3 (current)** — knots = K1..K4 of six (K5 = 0.930304, K6 = 1.050720 are version constants, not serialized), spikeMax per-seed, **benchLo = the 100 m foothill bench, benchHi = the 220 m white plateau**; bench step (+0.008) and segment shapes are version constants in `HeightCurve.cs`. Because spikeMax is per-seed (v2+), blueprints are not reproducible from curve constants alone — that is why it is recorded. **Metadata only:** exported heights are already curved; nothing re-applies the map. Calibration provenance: `HeightCurve.cs` header + the task-05/06/07 reports. |
|
||||
| `TCRV` / `0x56524354` | 50 B base: `u16 curveVersion` · `f32 knot1..knot4` · `f32 spikeMax` · `f32 sea` · `f32 orangeCeil` · `f32 redCeil` · `f32 benchLo` · `f32 benchHi` · `f32 peakCap` · `f32 tailSlope`. **When `curveVersion ≥ 4`, a 36 B modulation extension follows:** `f32 benchAmp` · `f32 plateauAmp` · `f32 shelfSpanMin` · `f32 shelfSpanMax` · `f32 elevFreqIslands` · `f32 strengthFreqIslands` · `i32 benchSeedOffset` · `i32 plateauSeedOffset` · `i32 strengthSeedOffset` (record total 86 B; the length-framed section + version byte make the layout change safe for old readers of old files) | Optional — present iff the height-redistribution curve shaped this blueprint's `HGTS` (config `TerrainCurve: "v3"`); absent = raw legacy profile. **The `u16 curveVersion` selects the field semantics and the unserialized anchor set:** v1 — knots t1..t4, spikeMax = pooled calibration max, benchLo/Hi = the 50 m plateau's lo/hi. v2 — as v1 but spikeMax = the seed's effective raw pre-curve maximum (per-seed spike normalizer). v3 — knots = K1..K4 of six (K5 = 0.930304, K6 = 1.050720 are version constants, not serialized), spikeMax per-seed, benchLo/benchHi = the fixed 100 m / 220 m shelves. **v4 (current)** — as v3, but benchLo/benchHi are the shelf **BASE** anchors and the extension record carries the spatial-modulation parameters: shelf elevations vary ±benchAmp/±plateauAmp and shelf strength blends the output span across `[shelfSpanMin, shelfSpanMax]`, via Simplex fields seeded `resolvedWorldSeed + seedOffset` at `freq/MapSize` (frequencies stated in undulations per island width). Because spikeMax is per-seed (v2+), blueprints are not reproducible from curve constants alone — that is why it is recorded. **Metadata only:** exported heights are already curved; nothing re-applies the map. Calibration provenance: `HeightCurve.cs` header + the task-05/06/07 reports. |
|
||||
| `WBID` / `0x44494257` | `MapSize²` × `u16` water-body id, same pixel order as `HGTS` | Optional (absent = no water data, e.g. a legacy re-encode). `0` = no water, `1` = **the** ocean body, `2..N` = lakes. Ids assigned in deterministic scan order (X outer / Y inner, first-encountered pixel), lakes labeled with the **same 4-connectivity as `CalculateTrueOcean`**. Membership is exactly the generator's water classification — the biome grid's Ocean/Lake pixels and this grid's nonzero pixels are the same set **by construction** (shared predicates). Length must equal `2·MapSize²`. |
|
||||
| `WBTB` / `0x42544257` | `i32 count`, then per body (20 B): `u16 id` · `u8 type` (0 ocean, 1 lake) · `u8 salinity` (0 fresh, 1 salt) · `f32 surfaceLevel` · `i32 pixelCount` · `f32 centroidX` · `f32 centroidY` | Optional, paired with `WBID`. **`surfaceLevel` is a documented TRANSITIONAL rule:** one flat level per body — `GetSeaLevel` at the body's pixel centroid (ocean: at the map centre) under the still-live latitude field; superseded by the flat-scalar sea model (minted, lands with the coast change set). The field's per-pixel slope is deliberately NOT baked into any section. **Salinity is a provisional default** (ocean salt, lake fresh) — a placeholder for the future fresh/salt irrigation mechanic, not a mechanic. |
|
||||
| `WSRF` / `0x46525357` | `MapSize²` × `u16` quantized water-surface elevation, same pixel order | Optional, paired with `WBID`. `0` is the reserved **no-water sentinel**; a real level `L` (raw height units) encodes as `1 + round(L × 32768)` so it can never encode to 0; decode `(q − 1)/32768` (`BlueprintFormat.EncodeWaterLevel`/`DecodeWaterLevel`). Covers `[0 … ~1.99997]` raw at `1/32768` raw ≈ **7.7 mm** of world height (1 raw = 251 m) — far finer than the 1 m voxel. Nonzero exactly where `WBID` is nonzero; the value is the pixel's body level. |
|
||||
|
|
@ -106,10 +106,11 @@ body).
|
|||
which model produced it (the `WBTB` levels are the observable).
|
||||
- **`SkipRoads`** (bool, default false) — exports with present-but-empty road sections (see the
|
||||
road-section table note).
|
||||
- **`TerrainCurve`** (`"v3"` | `"off"`, default `"v3"`; `"v1"`/`"v2"` retired by successor
|
||||
- **`TerrainCurve`** (`"v4"` | `"off"`, default `"v4"`; `"v1"`–`"v3"` retired by successor
|
||||
recalibrations and rejected loudly) — whether the height-redistribution curve (the terraced
|
||||
ascent: 59 % orange lowlands, 100 m foothill bench, 220 m white plateau, per-seed-normalized
|
||||
420 m summit spires) shapes `HGTS`. Biome/water classification is curve-invariant by
|
||||
ascent with spatially modulated shelves: 59 % orange lowlands, foothill bench 100±12 m, white
|
||||
plateau 220±20 m, per-flank shelf strength, per-seed-normalized 420 m summit spires) shapes
|
||||
`HGTS`. Biome/water classification is curve-invariant by
|
||||
construction (it classifies the retained uncurved heights); town positions and everything 3D
|
||||
follow the curved terrain. When on, `TCRV` records the effective parameters including the
|
||||
per-seed `spikeMax`.
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ Generates the entire 2D blueprint. Roughly in order:
|
|||
2. **Topography** — FastNoiseLite base height plus a mountain spine, minus a squircle distance
|
||||
falloff, giving a guaranteed island. Noise frequency is divided by `scaleFactor`
|
||||
(`MapSize / 1024f`) so terrain features stay the same real-world size at any map profile.
|
||||
When `TerrainCurve: "v3"` (the default), the calibrated height-redistribution curve
|
||||
(`HeightCurve.cs` — the terraced ascent: flat farmable lowlands, a walkable 100 m foothill
|
||||
bench, the white mountain-town plateau at 220 m, and a per-seed-normalized summit spike to
|
||||
the 420 m cap: every island's tallest point reaches the ceiling) reshapes above-sea terrain
|
||||
When `TerrainCurve: "v4"` (the default), the calibrated height-redistribution curve
|
||||
(`HeightCurve.cs` — the terraced ascent with spatially modulated shelves: flat farmable
|
||||
lowlands, a walkable foothill bench at 100±12 m, the white mountain-town plateau at
|
||||
220±20 m — shelf heights and strength drift across the island so no two flanks wear the same
|
||||
ring — and a per-seed-normalized summit spike to the 420 m cap) reshapes above-sea terrain
|
||||
after noise/falloff/Trench and before the crater carve; biome classification reads a
|
||||
retained uncurved map, so biomes are identical either way. Drops the `0_height` hillshade
|
||||
snapshot (hypsometric bands × NW hillshade) in both modes.
|
||||
|
|
|
|||
Loading…
Reference in a new issue