guts/docs/progress/a-progress.md
jing 111ade7d12 [lane A] The swept room + the acid sea, built — and it corrected me four times
The shape read in LANE_A_NOTES was written from reading code, so I built it to
find out if it was true. Flyable: web/dev/laneA_world.html?dbg=1&assets=1&lvl=swept
Nothing here is imposed on anyone: every addition is additive and a level that
opts out behaves exactly as today. C can bin the whole proposal and lose nothing.

WHAT THE PROTOTYPE DISPROVED (my own cost estimates, all four):
- "radial resolution must scale with radius" — wrong. 64 segments is a 0.05u
  circle error at r=70. The arena needs it because it fbm-displaces; the tube's
  wave is smooth in theta. No change made.
- "cap geometry at the span ends" — a thinko. The canal is continuous; a room is
  a fat part of it. Only the fundus dome caps, and it stays an icosphere.
- cost — cheaper than feared: 9 draws / 98k tris worst-frame for a radius-70
  cathedral vs 8 / 74k for the L2 corridor. No leak over a full sweep.
- "one schema flag" — held. `segments[].mode: "open"` is the entire ask.

THE TWO REAL COSTS, NEITHER PREDICTED:
1. D's `tile[0]` is a COUNT, not a density — only a texel size if radius never
   changes. Measured 6.1:1 smear at r=70. The wall now derives the count from
   each ring's own arc length (aRadius attr + uThetaSpan); D's authored numbers
   keep their exact meaning at their reference radius, no re-authoring. That fix
   then laid a seam down the canal (a fractional count can't wrap) -> rounded to
   an integer, seam gone. Not a no-op on corridors: L2's hiatus takes 3 repeats
   where it took 4, which is the texel size correctly holding still as the pipe
   narrows. Eyeballed.
2. MY OWN PINCH GUARD WAS WRONG and would have blocked C. The fixture scored
   1.30 and "failed" the >1.5 law; it was never bent. stats() divided the
   tightest turn ANYWHERE by the widest radius ANYWHERE — 996 units apart, a
   bend in the radius-13 pylorus against the radius of the sea. Locally its
   worst point is 6.4. pinchRatio is now min over s of turnRadius(s)/radius(s).
   Provably one-directional (global <= local by construction) so nothing that
   passed can fail; real levels GAINED headroom: L2 3.32->4.16, L3 1.91->6.99,
   L1 2.11->6.06. This mattered — the guard is what backs the round-1 promise
   that C never has to think about curvature.

THE ACID SEA (world/acid.js, `level.acid {from,to,height,biome}`):
Flat emissive #c8ff3a, level and NOT tube-following — that's the mechanic. The
best find of the session: `height` is ONE NUMBER that tunes the level. Measured:
-18 -> 0% of the sea floor is dry shallow, -55 -> 14%, -62 -> 48%. So C's "position
IS the resource" falls out of the radius wobble they already author — the mucus
shallows are just "where the wall rises above the waterline", nothing to place —
and rising acid literally drowns them: free escalation, same scalar their event
pump drives. Also disproved my own claim: the centreline stays level (+/-1u over
700u), so shallows come from radius wobble, NOT the canal's bends. C must author
vertical bends deliberately if they want depth by anatomy.

Stated plainly, not papered over: the waterline is prototype quality (the plane
meets faceted rings and the shoreline steps). Acid does not drain the coat —
depthAt(pos) is the hook and the cost is Lane B's call. Nothing drives height but
DBG until C's events do.

qa GREEN incl. the new provenance gate; spline selfcheck green; L2 corridor
re-eyeballed for regression. Rulings requested from F in NOTES §-> Lane F.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 18:04:16 +10:00

110 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Lane A — progress log
## 2026-07-16 · Round 2 — crest law, TBN walls, the colorspace re-eyeball, stomach shape read
Two halves: the original session (cut off pre-NOTES; work rescued by F as `f0982e7` — crest
speed law + selfchecks, ±25 radius taper, schema-v2 `wave.amp` as per-vertex `aWaveA`,
colorspace law in the wall, TBN + matcap + dual detail, `sample(s,out)`) and this resuming
session, which closed out the lane's round-2 list:
- **Tint re-eyeball under the colorspace law: all six ART_BIBLE tints stand, `biomes.js`
untouched.** The wash was the shader's round-1 constants, tuned on the raw framebuffer;
post-law the rim flooded every grazing angle. Retuned in `wall_material.js` (rim pow/gain,
both detail curves, sheen, matcap — values + rationale in-shader). Verified on a new
six-biome contact sheet (`?lvl=biomes`, kept as permanent kit), the real L2 hiatus, and an
arena interior; qa GREEN throughout. Evidence: `docs/shots/laneA/round2_tint_*.png` + two
`*_retuned` frames.
- **Ruling #5 executed**: harness → `web/dev/laneA_world.html`, + `DBG.post()` to the house
shot sink. `_fixture.js` stays — the spline selfcheck (qa gate) asserts against it; now
documented in-file.
- **Stomach-arena shape read → C (task #7)**: recommend the spline-swept room (arena = "open"
mode over an s-span, tube pipeline at room radii; fundus dome stays a welded icosphere;
chained spheres rejected — crease rings + union collision math). Full argument in
LANE_A_NOTES §→ Lane C; sketch `docs/shots/laneA/round2_stomach_arena_sketch.svg`. Triplanar
deliberately skipped: the swept room would obsolete it where it matters.
- Housekeeping: `guts-a` dev server on 8145 in launch.json; sink 8144 reused.
Then, same session, past the round-2 list — the shape read was written from reading code, so I
built it to find out if it was true. It wasn't, four times:
- **The texture set is complete** (`3a6dbc3`). Generated `wall_oral_a/b` + `wall_colon_a/b` +
normals on MODELBEAST flux_local, **$0.00**, D's pipeline unchanged — because the tint eyeball
could only judge 3 of 6 biomes against a real pack, and a stand-in can't ratify a tint. Seams
0.741.36 (D's "indistinguishable" band). Appendix wears the colon pack at gold tint — it IS
colon tissue; ART_BIBLE's "one texture, two biomes" law for zero bytes. **oral_a took three
subjects** and taught a rule worth more than the texture: naming an ORGAN summons its
silhouette ("tongue" → a dome), and papillae are 3D projections so perspective tiles into
starbursts — prompt the tissue's SURFACE, not its FEATURES.
- **Found a provenance defect in D's pack**: `batch_textures.json` recorded, for 4 of 6 walls,
the prompt from the framing experiment D *rejected*. `record()` only runs on generation, so
reverting a prompt while keeping its image drifts the record silently — and it breaks the
script's own promise that regeneration is always possible. Proved it by regenerating
esophagus_a at seed 1101 under both prompts (`round2_provenance_probe.png`). Records
re-pointed, `--verify-provenance` + qa gate 5b added so it can't recur.
- **Prototyped the swept room + acid sea** (`?lvl=swept`), and it corrected my own cost
estimates: radial resolution does NOT need to scale with radius (64 segs = 0.05u circle error
at r=70), caps were a thinko (the canal is continuous — a room is a fat part of it), and it's
cheap: **9 draws / 98k tris** for a radius-70 cathedral vs 8/74k for the L2 corridor, no leak.
The two real costs were ones I hadn't predicted: **D's `tile[0]` is a count, not a density**
(measured 6.1:1 smear at r=70 — now derived from each ring's arc length, D's numbers keeping
their meaning), and **my own pinch guard was wrong** — it divided the tightest turn anywhere
by the widest radius anywhere, 996 units apart, and false-failed a valid room at 1.30 (locally
6.4). Now local; only ever loosens; real levels gained headroom (L2 3.32→4.16, L3 1.91→6.99).
- **The acid sea's height is a design dial** and it's the best thing I found: one scalar tunes
how much of the sea floor is dry shallow (18 → 0%, 55 → 14%, 62 → 48%), and C's "position
is the resource" falls out of radius wobble they already author. Rising acid drowns the
shallows = free escalation. Also disproved my own assumption: the centreline stays level
(±1u over 700u), so shallows come from radius wobble, NOT from the canal's bends.
Still open for A (round 3): harden the swept room **if C takes it** (the waterline is the real
work), wire acid height to C's events, villi band, sphincter geometry, slug-map deletion on D's
rename ping. Not claiming: **the large_intestine tint is unratifiable** until someone owns the
"scanner light" its design depends on — GUTS has no lights by law, so that biome is murk by
construction. A near-field inverse of the fog term would be ~5 lines; it needs C/B to own the
mechanic first.
## 2026-07-16 · Round 1 — the canal, v0
Built `web/js/world/`: spline + parallel-transport frames + arclength LUTs, chunked streaming
tube, synthetic-scanner wall shader with vertex peristalsis, biome registry, arena shells v0,
noclip flycam, headless selfcheck, dev harness. Contract per TECH.md §THE WORLD CONTRACT,
drop-in for the stub.
**The game boots it.** `/?dbg=1` (no `?stub`) runs Lane A's world on C's `L2_esophagus`,
3600 units, hash `cefc4f83`, zero console errors. C's registry landing mid-round is what
unblocked `boot.js`'s `pickWorld()`; no shell change was needed.
Measured (dev.html, C's real L2 + D's real pack, 1920×1080, `renderer.info`):
draws **8** worst-frame over a full-canal sweep (budget ≤150) · tris **74,420** (≤500k) ·
geometries 6 → 6 across a full sweep and back, **no leak**, 0 after `dispose()` ·
load **<120 ms** (<2 s) · pinch ratio L2 3.32 / L3 1.89 (>1.5). fps deliberately **not**
claimed — the screenshot pane runs tabs hidden, which pauses rAF, and `gl.finish()` didn't
sync; needs a real window. Determinism: node and browser agree on the hash.
Three defects the checks caught that eyeballing would not have:
- **Tube folded through itself** on a wide+curvy join (turn radius 9.9 vs tube radius 17.2).
Root cause: centreline amplitude authored in units. Fixed by solving amplitudes from a
curvature budget, so `curviness` means "fraction of the pinch limit" and C can't author one.
- **Arena at 720 tris** — three's polyhedron `detail` is `20*(detail+1)^2`, not `20*4^detail`.
Now solved for ~3u spacing from the arena's own radius.
- **Acid sea rendered as a black rectangle** — biome fog is tuned for 100u corridors, C's arena
is 360u across. Arena fog is now sized to the room.
Also caught, and both would have rotted silently: the browser served a **stale cached
`biomes.js`**, so the first evidence set was shot at the old wave amplitude (re-shot); and D's
texture keys (`wall_smallint_a`) don't match my biome ids (`small_intestine`), which under the
assets-optional law fails to procedural forever with no error (slug map added, standardisation
proposed to D).
Decisions: peristalsis phase `K(s) = ∫k ds` with `k = OMEGA/flow(s)` ⇒ crest speed == local flow
(so "surf the crest" == "ride the current") · esophagus wave amp 0.9 → 1.4, measured, moves
`wallRho` for B · chunk seams align to biome joins, arenas own their span · one uv attribute,
tiling derived in-shader · colorspace left matching the stub, F to rule.
Evidence → `docs/shots/laneA/`: `round1_real_game_boot` (boot.js running Lane A's world),
`round1_L2_textured` / `round1_L2_procedural_fallback` (same pose, with and without D's pack —
the assets-optional law), `round1_L2_curve`, `round1_L2_wave_crest`, `round1_L3_arena_acid_sea`.
Open for round 2: triplanar arena shells + acid plane, villi band, normal/matcap TBN, sphincter
seam geometry. Full detail + per-lane asks in `LANE_A_NOTES.md`.