Files
settled-reach/docs/workshops/body-map-viewer/body-map-viewer-workshop-brief.md
T
jpmschweitzerandClaude Fable 5 29c22cb728 docs(meta): body-map-viewer workshop — rounds, measurements, outcomes, as-built briefing
The complete workshop record: four round-1 positions, five round-2 syntheses
(incl. Troblum's adversarial pass with addendum + final scorecard — all seven
findings resolved), both lead interviews, Qatux's round notes and the 8-section
workshop-outcomes.md (the lakes message-crossing documented as process
history), measurement ⑥ (set_pixel/c1) + the population-survey and chunk/S2
addenda in the measurement docs, the brief's appendix updated through ⑥, and
architecture-briefing-final.md — Jeroen's outline written back as-built
(six-level ladder, lakes, ~9MB resident global tier). README row: Complete.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 10:57:45 +02:00

20 KiB
Raw Blame History

title, description, type, status, workshop, created, decision_refs
title description type status workshop created decision_refs
Workshop Brief: Body Map Viewer — the stepped map handler Design the new Atlas map handler: server-side content determination per zoom step, client map-art rendering (RTT + screen-space vectors), stepped gridunit ladder to ground level, cache/TTL architecture, wire contract workshop active body-map-viewer 2026-07-25
D-166
D-226
D-227
D-243
D-239
D-225
D-010

Workshop Brief: Body Map Viewer — the stepped map handler

The Question

Jeroen's design outline (jeroen-outline.md) replaces the Atlas render mechanism: content determination moves to the server (per-gridunit data canvases generated per zoom step, doubling as seed input for the next tier down), the client becomes a map-art function (colorize, style, annotate — never invent geometry), and zoom becomes a stepped ladder from the body-global view down to ~10 px per 1 m tile. This dissolves the T-1176 error class at the root (there is no zoom-scaled canvas anymore) and turns the D-166 seamless-ladder mandate into a concrete serving + caching + rendering architecture.

The premises are settled (below). The workshop designs the remaining load-bearing pieces: the wire contract, the cache tiers, the step ladder itself, and four honest risk confrontations — against measured numbers, not extrapolation (the T-1143 planetary rung is the named cautionary tale).

Context — settled premises (not for relitigation)

From the outline + two clarification rounds (clarifications.md)

  • prep rulings (Jeroen, 2026-07-25):
  1. Lazy/late compute. Nothing computed in the game loop that game state doesn't need; smart precache allowed, never blocking user output. TTL = f(detail level, time, distance); player focus = character location AND atlas viewport.
  2. Server determines content; client draws art. The server answers "what is at this world coordinate at this zoom step"; the client styles it. Derivation is CPU/Rust server-side only — GPU is presentation only (locked; the two-language-mirror liability, T-1170 precedent).
  3. Stepped zoom. Scroll clicks through discrete levels; cursor-anchored centering, edge-scroll pan, and full-zoom-out-reset survive. A client-side morph/tween between steps is an investigation item (cosmetic only, never re-derivation). Supersedes the continuous-multiplier zoom (T-1143 ruling 3) — recorded as a deliberate revision at filing.
  4. Vocabulary: tile = the 1×1 m ground unit (D-243), only. Gridunit (at zoom level) = the per-step data cell. The ladder bottoms out at ~10 px per tile on the viewport's smaller axis.
  5. Data resolution is a tunable: 1 gridunit per screen px ideal; ~1 per 5×5 px display unit acceptable ("crisper is better, but the computer must not catch fire"). Decided by measurement.
  6. Hydrology = deterministic equilibrium. Lake fill, overflow re-routing, gorge carving: a settled end-state, pure function of seed + moisture/climate, extending D8 drainage. No stateful simulation.
  7. Render baseline (locked): per-step data canvas → render-to-texture terrain layer (texel-exact, drawn 1:1 or at the tunable ratio) + unscaled screen-space sibling layer for vector annotations (literal px sizes). Open within the baseline: shader-vs-CPU styling (c1) and the step morph.
  8. Step boundaries = compute-chunk boundaries for the deterministic generators.
  9. Jeroen's cache direction (to cost and confirm, not overturn): the primary atlas cache lives client-side — received step canvases are retained (compressed to what's needed) and simply not re-requested; determinism makes this safe (a canvas for a fixed seed never changes). Only sim-state components (frozen/flooded — "maybe shorter ttl on the climate sim state components") need invalidation at all. Open within this premise (Jeroen, sign-off round): whether the client needs a dedicated cache store — disk-backed, redis-like TTL semantics, self-cleaning records — rather than in-memory retention only; his lean: "on disk probably, but with self cleaning of cache records." D-227's discipline applies client-side too: whatever the store, it is an evictable cache, never a source of truth.

Governance delta (full analysis: tyre-implications.md §1): amends the D-166 corollary (anti-over/undersampling becomes a per-step property — repointed, not deleted), T-1143 ruling 3 (stepped supersedes continuous), the select_rung coverage walk (replaced by step index), D-243 (adds gridunit), and likely triggers the tagged-envelope migration (D-225's deferral — expected scope, not a risk to avoid). Survives untouched: D-227 derive-don't-store (the TTL cache is its concrete eviction policy), D-010, D-226(d)'s whole-body prohibition, D-169/D-170, and the T-1170 carrier three-way rule (repointed "window" → "step canvas").

Red flags the workshop must confront (stated honestly, not to relitigate)

  1. Between-step magnification. Just before a step-cross the held texture is a magnified coarser composite — the exact thing D-166 forbids — for one step interval. Step count + px-per-gridunit are the knobs that keep it imperceptible; the D-166 amendment must own this.
  2. "Always keep global" memory. ~1.6 MB/body at 5×5 ≈ ~440 MB across ~273 bodies if never-evict; ~13 GB at 1×1. The cache deliverable produces a number, not a vibe: always-derivable-fast vs permanent residency (vs disk tier — which must stay consistent with D-227).
  3. Canonical-vs-viewport canvas is a governance boundary at the deep end. A canonical fixed canvas at 1 m spacing is a near-whole-body metre-resolution derivation — violating the D-226(d) prohibition that survives. Viewport-sized keeps the deep ladder legal by construction. Not just a cache tradeoff.
  4. Cliff/multi-height gap. Settled hydrology produces gorges; a gorge is two heights in one gridunit; the sketched payload carries one height. Either a vertical-structure field at Phase-4 Atlas scope, or cliffs are Phase-5 geometry with a "steep" classification on the map. The hydrology measurement must output the cliff representation, not just cost.
  5. Tagged-envelope migration is expected scope — tier: challenging but doable (executing D-225's planned deferral, not inventing a migration).

Participants

Dudley, Araminta, Stig, Tyre, Troblum (round 2 only) (+ Qatux documenting, SI reviewing ticket outputs)

Questions for participants

Dudley:

  1. The equilibrium hydrology solver: algorithm choice (priority-flood family with overflow re-routing + gorge carving), measured cost at 512×256 and 4K-class, and the cliff/two-heights output representation (red flag 4).
  2. Step-canvas generation and the canonical-vs-viewport data canvas (red flag 3): cost, cache shape, and the D-226(d) boundary at the deep steps.
  3. Compute-chunk partitioning: how a step's derivation decomposes across the Rayon queue (chunked par_iter at 330K–8.3M cells — measured, not extrapolated) with step boundaries as the chunk boundaries (premise 8).
  4. Cache tiers server-side: what "always keep the global level" costs across ~273 bodies (red flag 2), and the TTL(detail, time, distance) eviction policy as D-227's concrete instantiation.

Araminta:

  1. Named-feature encoding (THE wire decision): dense classification rasters + sparse feature list vs inline identity vs ids-with-lookup — for rivers, settlements, roads, POIs and their names. Jeroen's constraint: "best fidelity vs wire contract possible; the information the client needs needs to be there." Feeds the tagged-envelope call.
  2. The per-gridunit payload schema: exactly which typed fields the map-art function receives (biome, ground type, height, flooded/frozen/sea, river/settlement presence + identity), and what the client is allowed to do with them.
  3. Encoding continuity across steps: one colorizer family (T-1143 §6), average-back across step boundaries, and what "different classes of content at lower zoom" (forest → clearings/ponds) means for the classification vocabulary.

Stig:

  1. The client map-drawing component: structure of the RTT terrain layer + unscaled screen-space annotation layer, replacing the _canvas.scale model; what of the existing atlas/ cluster survives vs retires (T-1158 decomposition folds in here).
  2. Step-cross experience: hold-fetch-swap, the morph investigation (cosmetic tween only), ImageTexture upload cost per step, and the client-side cache (premise 9: retain received canvases compressed, stop re-requesting; sim-state components TTL'd).
  3. Overlay compositing under RTT (temperature/moisture/vegetation toggles, glaciation modifier): shader vs CPU styling — the (c1) decision, including T-1175's tapering/width grammar coming along for free if shaders win.
  4. The client cache store (premise 9's open half): does the map cache need a persistent, disk-backed store with self-cleaning TTL records (redis-like semantics in an embedded shape), or does in-memory retention suffice per session? Fact base (verified, sign-off round): SQLite ships with the game but not inside the Godot client — the Rust server (a local subprocess) owns the SQLite path (systems.db, D-138 persisted state); the client's only addons are gdUnit4 and messagepack. Three candidate shapes to cost (with Dudley on the first): (i) server-side SQLite cache DB — zero new dependencies, "client-primary" reads as local-machine-primary (a warm local subprocess answering from disk is nearly as snappy as client memory); (ii) godot-sqlite addon in the client — a real client-side store, one new dependency; (iii) plain Godot FileAccess cache dir + index — no dependency, hand-rolled TTL sweep. Hard boundary in every shape: the cache is its own file — systems.db is the read-only canonical snapshot (asset-pipeline golden rule) and never doubles as cache. Size the store from the wire table (④); D-227's cache-never-truth constraint applies at every tier.

Tyre:

  1. Ratify the governance delta (§1 of your implications pass) as concrete amendment texts: D-166 corollary repoint, T-1143 ruling revision, D-243 gridunit entry, the tagged-envelope decision.
  2. The gridunit ↔ D-243 reconciliation: does gridunit spacing snap to the absolute-metre rungs or float freely per viewport/step? (Your "most load-bearing vocabulary reconciliation.")
  3. The determinism boundary in the new split: server-resolved geometry vs client art — where exactly may the client interpolate ("tween rivers/roads") without creating a second truth?
  4. The cliff/multi-height ruling proposal (with Dudley's measurement output).

Troblum (round 2):

  1. Stress the cost story against the measured appendix — find the extrapolation.
  2. The memory budget (red flag 2) and the wire-size table under realistic play patterns (step-thrashing, body-hopping).
  3. The deepest-step extent vs D-226(d) (red flag 3) — verify the chosen canvas policy actually holds the boundary.

Questions for Jeroen (lead interview, each round):

  1. Map time axis: climatology vs current sim state for frozen/flooded — your "shorter ttl on climate sim state components" hint as the working model?
  2. Step count and the step factor (largest → visible tile), once the measured costs frame what a step can afford.
  3. Canonical vs viewport-sized data canvas — you saw value in both; the deep-step governance boundary (red flag 3) may force the split answer (canonical shallow, viewport deep).
  4. Phase-5 reuse: is the map-drawing component the future in-world viewport's code path, or Atlas-only? (Scopes the component's ambitions.)

Workshop Format

2 rounds + lead interview per round; extendable at Jeroen's call — after each round Jeroen is asked whether another round is needed, for as long as he feels necessary (workshops are not closed early on partial convergence).

  • Gate: round 1 does not start until measurements ①–④ below are done and their numbers are in this brief's appendix (⑤ may land during round 1).
  • Round 1 — positions. Each core participant answers their question slice against the measured numbers, in writing ({agent}-round1.md).
  • Lead interview 1. Jeroen rules on what round 1 surfaced (step count, canvas policy, map time axis).
  • Round 2 — synthesis. Cross-cutting decisions: the wire contract + tagged-envelope call, gridunit↔D-243, cache-tier architecture, the cliff ruling. Troblum's adversarial pass runs here against the whole picture.
  • Lead interview 2 → sign-off or another round.
  • Filing: D-records claimed and written before dismissal (amendment set per the governance delta + the new render-architecture record), including the explicit deprecation sweep (Expected Output 2) — a Clerk consistency audit verifies no conflicting record or ticket is left standing before the team is dismissed; tickets drafted by the lead, reviewed by SI; Qatux produces workshop-outcomes.md and diagram updates.

Pre-workshop measurement appendix — MEASURED (2026-07-25, 16-core / Rayon 14 / RX 9070, release builds; all numbers post-date a background-load closure with stability re-runs — details + repro commands in each linked doc)

The gate is satisfied: ①–④ measured, ⑤ measured. Round 1 may start.

# Ticket Headline result Doc
① T-1177 Settled hydrology VIABLE: 512×256 ~24 ms/body; all 273 bodies Rayon-parallel ~0.7–0.8 s; 8.3M cells ~5.7 s single-thread (no production path needs it synchronously). Cliff representation: dominant height + channel_depth + cliff_edge flag. Finding: gorge carving is structurally RARE (priority-flood finds true spill levels; zero carved cells at production scales — needs chained-basin geometry). Solver: priority-flood + Dijkstra overflow, pure function, determinism-proved. POPULATION SURVEY addendum (post-adversarial, Troblum finding that the 273-body bench was one body solved 273×): all 267 real committed bodies solved independently, ~0.86s total, ZERO carved cells / zero cliff_edge cells population-wide (267/267) — the rarity finding upgrades from "one real body + structural argument" to "not observed anywhere in the real population," strengthening the cliff Phase-4 wire-cost case. t1177
② T-1178 Parallel throughput HOLDS at scale (the T-1143 extrapolation gap, closed): ~190–220 ns/cell parallel flat from 330K→8.3M cells; 330K canvas ~64 ms, 2.07M ~0.4 s, 8.3M ~1.7–1.8 s (7.5–8.8× speedup); single-thread flat ~1.65 µs/cell, matches prior baseline within 8%. Throughput cross-validated on three bodies across two call paths (square real-build_district_window_layer = courses-light, 3–10 in window; rectangular replica loop = courses-empty by construction — agreeing within 0.3%); the courses-inclusive rate at real production density is measured once, GJ1c 330K with 18 courses at 195.0 ns/cell (within 2%, consistent with the <5% course-cost bound). t1178+t1154
③ T-1154 Block GO, Tile GO on cost (~1.8–1.9 µs/cell, same band as District/Quarter). Octave cutoff buys ZERO below District spacing (verified: wavelength table bottoms at 128 m). Deepest-step realistic canvas (216×384 m @ 1 m = 83K cells): ~17 ms parallel — trivially interactive. voxel_relief already in the Atlas path; voxel_mosaic untouched by it. Real gates are wire carrier + D-226(d) canvas policy, not cost. t1178+t1154
④ T-1179 PNG-per-field wins everywhere — smallest AND fastest: 330K canvas = 638 KB (0.32× raw, 5.4/3.6 ms enc/dec) vs raw rmp 1.99 MB; RLE loses to raw (elev/temp near-noise per cell). No encoding brings a step canvas near the existing windowed-payload budget (best case 21× the ~30 KB cap at the smallest size; 563× at 8.3M) — the tagged-envelope migration cannot be dodged by payload optimization. Whether the letter of the D-226 §2 field-count rule is what triggers it is a workshop synthesis call, not a measured result. Corrected density: 6.00 B/cell measured raw. t1179
⑤ T-1180 Upload cost is a non-issue: worst case (8.3M px RGBA8 create) ~3.2 ms median, ~2.4–2.9 ms frame-delta spike — never near the 16.6 ms budget. L8 is 4–9× cheaper at every size (~0.5–0.7 ms at 4K). Prefer texture.update reuse on step-cross; use L8 for single-channel planes. Windowed-only measurement (headless renderer fakes uploads). t1180
⑥ round 2 (lead interview 1 ruling) MEASURED — CPU colorize is the c1 gate, not upload. Image.set_pixel flat ~78 ns/cell (330K→8.3M, no cliff): 330K ~25.7 ms, 2.07M ~165 ms, 8.3M ~644 ms. Direct PackedByteArray write is ~2× SLOWER (~153 ns/cell) — counter to the naive "skip the method call" assumption; prefer set_pixel. At the realistic per-step canvas size (330K, Dudley's viewport-sized recommendation) colorize is cheap (25.7 ms) and ranks second only to server derivation in the arrival-side cost chain (ahead of ④'s decode and ⑤'s upload); at the 8.3M stress-ceiling size it becomes non-trivial (~1/3 of server derive time at that size) — reinforces viewport-sized canvases over any canonical whole-canvas colorize. Headless-valid (pure CPU, no GPU path, unlike ⑤). t-setpixel-c1

Bench code (all #[ignore]d release tests): server/src/atlas/hydrology_equilibrium.rs + server/tests/hydrology_equilibrium_bench.rs, server/tests/bmv_gridunit_bench.rs, server/tests/wire_encoding_bench.rs. Client-side: client/tests/ (temporary uncommitted drivers per measurement doc, ⑤/⑥).

Input Documents

Doc Why
jeroen-outline.md The design, verbatim
clarifications.md Settled premises + deferred deliverables, verbatim answers
tyre-implications.md Governance delta, candidate re-ranking, red flags
prep-grounding.md Current mechanism, error-class evidence, measured baselines
docs/architecture/atlas-zoom-ladder-t1143.md The predecessor ladder design + Jeroen's three rulings
docs/architecture/river-courses-t1170.md The carrier three-way rule (survives, repointed)
governance/decisions/architecture.md D-166 amendment+corollary, D-226 chain, D-227, D-243, D-239, D-225

Expected Outputs

  1. D-record set: the body-map-viewer render architecture (new record) + the amendment set from the governance delta (D-166 corollary repoint, T-1143 ruling revision, D-243 gridunit vocabulary, tagged-envelope decision, cache/TTL policy as D-227's instantiation).
  2. Explicit deprecation sweep — no conflicting record left standing (Jeroen, sign-off round). Every DQR record and ticket that conflicts with the decided setup is explicitly amended, superseded, or deprecated in the same filing pass — never left silently contradicting. Starting set = the governance delta's known conflicts (the D-166 corollary sentence, T-1143 ruling 3 and its select_rung coverage-walk model, the windowed-family ceiling if the tagged envelope is chosen); completed by a systematic consistency sweep (Clerk audit) to catch conflicts the delta did not name. Conflicting tickets are cancelled or re-scoped with the supersession noted on the ticket (T-1158 subsumed, T-1154 repurposed as measurement ③, T-1175/T-1157/T-1174 reconciled in the ticket plan).
  3. The step ladder: step count, step factor, per-step gridunit spacing and its D-243 relationship, the deepest step's canvas policy.
  4. The wire contract: per-gridunit payload schema + named-feature encoding + envelope framing, with the measured wire-size table.
  5. The cache architecture: client-primary retention (premise 9) + the client store decision (in-memory vs disk-backed with self-cleaning TTL) + server tiers + TTL formula + the global-tier memory answer.
  6. Ticket plan: implementation chain (measurement-informed), explicitly reconciling T-1158 (viewer decomposition — subsumed), T-1175 (polish — styling engine dependent), T-1157 (capture harness — the new mechanism's verification story), T-1174, and the retirement path for the _canvas.scale model.
  7. workshop-outcomes.md + updated diagrams (Qatux).