docs(decisions): amend D-202 — file-based 16-bit heightmap, relief rename (#963)
Supersede the atlas_body_heightmaps BLOB store with a per-body 16-bit grayscale heightmap.png (2048x1024, canonical elevation) next to a renamed reliefmap.png (color display render). Records the rationale (binary merge-conflict avoidance + DB size + viewable/deterministic single source), the multi-resolution split (Layer 1 downsamples to 512x256), and the dropped table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -921,7 +921,13 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
- The Rust loader reads the BLOB via `bytemuck::cast_slice::<u8, f32>()` after fetching from SQLite. No endian conversion needed on LE-native systems; the pipeline stores LE explicitly.
|
||||
- Only inhabited bodies receive heightmap rows at build-time. Uninhabited bodies are generated on-demand (runtime-background tier, D-200).
|
||||
- This table is populated by the `import_heightmaps` build-time step in the asset pipeline (D-191 §9 pipeline order). It is read-only at runtime.
|
||||
- **Rationale:** Storing heightmaps in `systems.db` keeps the DB as the single source of truth for all generation inputs, avoids a separate file-fetching path in the Rust server, and allows the pre-push hook (asset pipeline rules) to detect stale heightmap data. The float32 LE layout matches what NumPy and PIL produce natively, minimizing conversion overhead in the Python pipeline.
|
||||
- **Amendment (2026-05-23, [#963](#)):** the DB-BLOB store is **superseded** by a per-body **file-based 16-bit grayscale `heightmap.png`** stored next to the body's other assets (path from `bodies.terrain_reference`). Rationale for the change: raw float grids committed inside a binary `systems.db` are the exact binary-merge-conflict trap the asset-pipeline rule warns against, and ~512KB×N bloats the DB; a per-body file matches D-203's on-demand model and keeps `systems.db` lean. Concretely:
|
||||
- **Naming fix:** the existing color hypsometric render (today's `heightmap.png`, 1024×512 RGB) is renamed **`reliefmap.png`** — it is a relief visualization, not elevation. Display-only.
|
||||
- **Canonical elevation:** a new **`heightmap.png`** = 16-bit grayscale (luminance = normalized elevation), **2048×1024** (4× the old 512×256 sim grid; bounds install size while sub-pixel detail is synthesized by the lower cascade layers). It is the single source of truth — the reliefmap and all computed geography derive from it, so it is bit-identical/deterministic by construction.
|
||||
- **Multi-resolution:** the stored heightmap is high-res for the lower layers (region/block/tile sample local detail); **Layer 1** (continental drainage/basins/mountain-ranges) calls `BodyHeightmap::downsample` to the `GRID_W×GRID_H = 512×256` working resolution first, decoupling continental compute cost (~45ms) from stored resolution.
|
||||
- **Rust loader:** `heightmap.rs::load_heightmap_png` reads the 16-bit grayscale PNG (via the `png` crate), normalizes to f32 [0,1]; rejects RGB (a reliefmap can't be misread as elevation). `sea_level` becomes body metadata carried alongside (not in the PNG).
|
||||
- **`atlas_body_heightmaps` is dropped**; `import_heightmaps.py` writes the PNG file instead of a DB row. The bake runs in the content pipeline (numpy/scipy) once; the runtime cascade is pure Rust loading the file.
|
||||
- **Rationale:** Storing heightmaps in `systems.db` keeps the DB as the single source of truth for all generation inputs, avoids a separate file-fetching path in the Rust server, and allows the pre-push hook (asset pipeline rules) to detect stale heightmap data. The float32 LE layout matches what NumPy and PIL produce natively, minimizing conversion overhead in the Python pipeline. *(Superseded by the #963 amendment above — the file-based model won out because the DB-as-single-source goal conflicts with binary-merge-conflict avoidance and DB size; a per-body committed PNG is itself a queryable, diffable-by-render asset.)*
|
||||
- **Ticket:** #901 (schema), #906 (import), #916 (Rust loader)
|
||||
- **Raised by:** Generation cascade workshop (#897)
|
||||
- **Cross-reference:** D-191 (atlas pipeline — heightmap source), D-203 (BodyWorldState — consumer), D-208 (D8 drainage — reads this table)
|
||||
|
||||
Reference in New Issue
Block a user