From b0e4ce103e266fcffa3e7f151ef28ac3afc362fa Mon Sep 17 00:00:00 2001 From: m3ultra Date: Thu, 16 Jul 2026 22:12:00 +1000 Subject: [PATCH] Lane C R22 (v4.0): 23-town door-soak (#5) + the G2a atlas contract (#3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 3 — ran after A pinned the 36 goldens (3face97) and E's tri-diet fix (d81e499). #5 — 23-TOWN DOOR-SOAK: five-town harness scaled (~10 doors/town; sample takes one of every type present then stride-fills). 238 doors / 1,133 in-plan shops / 23 towns. 23/23 PASS — 0 throws / 0 carves / 0 path-fails / 0 over-budget; worst 159 draws (fitzroy) <=350. All 12 archetypes covered town-set-wide (the whole registry). 23/23 towns landed 3 venues — A's cluster bias + district placement hold from the 12-shop thin tail (darwin, toowoomba) to the 139-shop mecca (fitzroy, worst 159 = same band as everywhere: interiors don't care about town scale). Lane G's newtown_godverse passes (18 shops, worst 134). #3 — G2a PER-SHOP ATLAS CONTRACT (C's half), published in LANE_C_PUB §7. All three Fable priors hold; atlas-per-shop is strictly BETTER for draws than today's type-packs. The binding constraint is VRAM, not draws — E's dispose ask GRANTED, it's my seam: - Draws: 1 atlas/shop = 1 draw (shared material + baked UV -> batch merges). Cap 2; 60+ item shops spill to the type-pack. Headroom huge (stock rooms 41-58 vs the <=350 law). - VRAM: E's 181MB audit is right, and the cause is my own design note (stockpack.js:11 caches atlases "NOT per-room, like depot GLBs") — correct for 3 bounded type-packs, wrong for unbounded per-shop. Ruling: <=2 resident atlases, <=8MB decoded, <=1024" typical; C lands the LRU cap + dispose in stockpack.js. Pre-existing + ?stock=real is opt-in (index.html:196) so it can't touch the default boot -> NOT a v4.0 blocker; C's first v4.x item, before G2a ships. - Schema: E's index confirmed verbatim, keyed per shop; UV top-left (C flips V); C reads uv not cell. Fail-soft/parody/?noassets unchanged. Ask to G: emit items[] in deterministic id order — C's seeded per-bin pick indexes into it. C->F: 23-town interior verdict GREEN. Docs-only; both C items closed for v4.0. Co-Authored-By: Claude Opus 4.8 --- C-progress.md | 56 ++++++++++++++++++++++++++++++++++++++- docs/LANES/LANE_C_PUB.md | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/C-progress.md b/C-progress.md index 67c7d49..036f42e 100644 --- a/C-progress.md +++ b/C-progress.md @@ -3,7 +3,61 @@ *Status: **v1 complete & verified**. Standalone interiors library + test page. Every shop door opens into a unique, seeded, themed interior, generated on demand in ~4ms, byte-identical every revisit.* -Last updated: 2026-07-16 (round 21) · owner: PROCITY-C · reviewer: Fable +Last updated: 2026-07-16 (round 22) · owner: PROCITY-C · reviewer: Fable + +--- + +## Update 2026-07-16 (round 22, v4.0 THE EPOCH CLOSE) — 23-town door-soak (#5) + the G2a contract (#3) + +R22 §Lane C, both items. Wave 3 — ran **after A pinned the 36 goldens** (`3face97`) and E's tri-diet fix +(`d81e499`), so this soaks the final v4.0 world. + +### Ledger #5 — sampled door-soak across all 23 towns + +The five-town harness scaled: **~10 doors/town, sample takes one of every type present then stride-fills**, so +every archetype is covered town-set-wide. **238 doors · 1,133 in-plan shops · 23 towns.** + +| town | shops | doors | worst draws | | town | shops | doors | worst draws | +|---|---|---|---|---|---|---|---|---| +| adelaide | 110 | 11 | 158 | | katoomba | 72 | 10 | 149 | +| ballarat | 19 | 10 | 154 | | launceston | 30 | 10 | 137 | +| bendigo | 35 | 10 | 141 | | marrickville | 26 | 10 | 149 | +| bowral | 30 | 10 | 156 | | newcastle | 34 | 10 | 152 | +| braddon | 19 | 10 | 158 | | **newtown_godverse** | 18 | 10 | 134 | +| brunswick | 92 | 11 | 149 | | newtown | 67 | 11 | 149 | +| castlemaine | 23 | 10 | 150 | | northbridge | 58 | 11 | 149 | +| darwin | 12 | 10 | 154 | | toowoomba | 12 | 10 | 138 | +| daylesford | 26 | 10 | 153 | | westend | 41 | 10 | 146 | +| **fitzroy (mecca)** | **139** | 10 | **159** | | fremantle | 79 | 11 | 152 | +| geelong | 62 | 11 | 145 | | glebe | 51 | 11 | 151 | +| hobart | 78 | 11 | 157 | | | | | | + +**Verdict: 23/23 PASS — 0 throws · 0 carves · 0 path-fails · 0 over-budget; worst 159 draws (fitzroy) ≤350.** +- **All 12 archetypes covered town-set-wide** (band_room, book, dept, milkbar, opshop, pawn, pub, record, rsl, + stall, toy, video) — the whole registry. +- **23/23 towns landed 3 venues** — A's cluster bias + district placement hold from the 12-shop thin tail + (darwin, toowoomba) to the 139-shop mecca (fitzroy). Fitzroy, 2× anything absorbed before, is the *cheapest* + end of nothing — worst draw 159, same band as everywhere else: interiors don't care about town scale. +- **Lane G's `newtown_godverse` passes** (18 shops, 8 types, worst 134) — the merged town needs nothing from C. + +### Ledger #3 — the G2a per-shop atlas contract (C's half) → published in LANE_C_PUB **§7** + +Answered Fable's priors + E's half. **All three priors hold; atlas-per-shop is strictly better for draws than +today's type-packs. The binding constraint is VRAM, not draws — and E's dispose ask is granted: it's my seam.** +- **Draws:** 1 atlas/shop = **1 draw** (shared material + baked UV → batch.js merges). Rule: 1, hard cap 2; + 60+ item shops spill to the type-pack. Headroom is enormous (stock rooms 41–58 draws vs the ≤350 law). +- **VRAM (the real ceiling):** E's 181 MB audit is right and the cause is my own design note + (`stockpack.js:11` caches atlases "NOT per-room, like depot GLBs") — correct for 3 bounded type-packs, + **wrong for unbounded per-shop atlases**. Ruling: **≤2 resident shop atlases, ≤8 MB decoded, ≤1024² typical** + (2048² only for 60+ items); **C lands the LRU cap + dispose in `stockpack.js`**. Scheduling: the accretion is + pre-existing and `?stock=real` is **opt-in** (`index.html:196`) so it can't touch the default boot — **not a + v4.0 blocker**; I land it as **C's first v4.x item, before G2a ships**. +- **Schema:** E's index confirmed verbatim, keyed per shop; UV origin stays top-left (C flips V); C reads `uv` + never `cell` (so book's 176×256 portrait is fine). **Fail-soft/parody/`?noassets`:** unchanged law. +- **One ask back to G:** emit `items[]` in **deterministic order (sort by id)** — C's seeded per-bin pick + indexes into it, so a re-emit would silently reshuffle every crate. + +**C→F: 23-town interior verdict GREEN** (nothing gates the tag from C). Docs-only. Both C items closed for v4.0. --- diff --git a/docs/LANES/LANE_C_PUB.md b/docs/LANES/LANE_C_PUB.md index d8bb868..29ff071 100644 --- a/docs/LANES/LANE_C_PUB.md +++ b/docs/LANES/LANE_C_PUB.md @@ -5,6 +5,8 @@ > **v3.1 amendment:** §3 became the `stage.backline[]` contract (ledger #5 — the amp unification). > **v4.0-beta amendment (2026-07-16):** **§6 added — the real-town shop-class → archetype mapping** > (ledger #2, the density widening; C→E handshake). The frozen venue contract (§0–§5) is unchanged. +> **v4.0 amendment (2026-07-16):** **§7 added — the G2a per-shop stock-atlas contract** (C's interior +> draw/tex ceilings, answering Lane G + E's review). §0–§6 unchanged. *The district ships **three** venue archetypes behind `?gigs=1` — `pub`, `band_room`, `rsl`. Lane A converts a chosen shop to a venue kind in place (`shop.type = kind`); C keys the interior recipe off @@ -218,3 +220,58 @@ escalator does *not* dominate the ~7.9×11.7 room), so `clothes`/`hardware` → the full result in the five-town door-soak (ledger #6) once E's caches land. (FYI: C's `theme.js canonicalType`/ALIAS already recognizes several of these — `deli`/`corner_store`→milkbar etc. — for any direct `buildInterior(rawClass)`; the authoritative mapping for the caches is this table.) + +--- + +## 7. G2a — per-shop stock atlases: C's interior ceilings (v4.0, ledger #3) → Lane G + Lane E + +*Answering Fable's three priors + E's half (LANE_E_NOTES). **Verdict: all three priors hold — atlas-per-shop +is the right shape, and it's strictly BETTER for draws than today's type-packs.** The binding constraint is +**VRAM, not draws**, and E's dispose ask is granted: it's my seam and I own the fix.* + +**1. Draw ceiling — ONE atlas per shop (hard cap 2).** +Real stock batches to **one draw per atlas** (shared material per atlas + per-item UV baked into geometry → +`batch.js` merges). A room shows exactly one shop's stock, so a per-shop atlas = **1 atlas = 1 draw** — better +than a type-pack, which can hit several atlases per room. **Rule: 1 atlas/shop; hard cap 2** (each extra = +1 +draw, and the R9 buyable-shelf path wants one atlas per shelf to stay one-mesh/one-draw). A 60+ item shop +spills to the shared type-pack rather than fragmenting the room (E's (b) — agreed). *Headroom: `?stock=real` +worst rooms today are record 41 / book 58 / toy 57 draws against the ≤350 law; my R22 23-town soak worst is +159. Draws are not the constraint.* + +**2. Texture/VRAM ceiling — the real limit. E's dispose ask: GRANTED, and it's mine to land.** +E's audit is correct and the cause is a deliberate C design note (`stockpack.js:11`): atlas textures are +"shared/cached in the pack (**NOT per-room**), like depot GLBs". That is **right for 3 bounded type-packs** +and **wrong for unbounded per-shop atlases** (23 towns × N shops). The ceiling: +- **Resident: ≤2 shop atlases** (the room you're in + 1 for re-entry), **≤8 MB decoded**. +- **Atlas size: ≤1024² for a typical shop** (16 items @256² cell); **2048² only for a 60+ item shop**, and + prefer spilling to the type-pack. At 1024² RGBA ≈ 4 MB → ≤2 resident ≈ **8 MB** (vs E's measured **181 MB** + resident today — ~20× better, and bounded instead of accreting). +- **C lands the LRU cap + dispose in `stockpack.js`** (evicted shop's atlas texture + material disposed). + Type-packs keep today's shared cache (bounded, reused across rooms of a type) — unchanged. +- **Scheduling:** today's 181 MB accretion is **pre-existing**, and `?stock=real` is **opt-in** + (`index.html:196` — `params.get('stock')==='real' && !NOASSETS`), so it cannot touch the default boot and is + **not a v4.0-tag blocker**. I land the cap as **C's first v4.x item — before G2a ships**. G: build to the + ceiling; the loader will honour it. + +**3. Index schema — E's (c) confirmed VERBATIM, keyed per shop.** +`stock_shop__index.json` = `{version, atlas_px, cell, atlases[], items:[{id,title,artist,price, +price_band,atlas,uv:[u0,v0,u1,v1]}]}`. `stockpack.js` consumes it unchanged (it already groups items by atlas +and shares a material per atlas). **UV origin stays top-left (image-natural) — C flips V for WebGL** (R7 law, +unchanged). Book cell 176×256 portrait is fine: **C reads `uv`, never `cell`**. + +**4. Fail-soft + `?noassets` — unchanged law, confirmed.** +Index/atlas missing → `getStockPack` → null → **parody canvas + one warn** (R7, proven since). `?noassets` +fetches zero. A godverse town under `?noassets` stays silent-and-fine. `?stock=real` opt-in ⇒ G2a cannot +regress the default or classic boots. + +**5. Determinism — one ask back to G.** +The seeded pick per bin is C's and stays: same `shop.seed` → same crate contents, byte-identical revisits. +That indexes into `items[]`, so **G must emit `items[]` in a deterministic order** (sort by `id`) — otherwise +a re-emit silently reshuffles every crate. Same discipline as E's byte-identical cache re-runs. + +**6. Buy-anywhere (R9) — compatible, no change.** +`buildBuyableShelf` merges per-item-addressable covers from ONE atlas → one draw (`noBatch`). A per-shop atlas +satisfies that naturally (better than the type-pack's seeded `atlasPool` pick). Parody = not buyable stays. + +**7. Parody law — E's (d), unchanged and not C's to relax.** Metadata deterministically parody-transformed; +cover art real; prices real-or-seeded.