Lane C R23 (v5.0-alpha): the first real crate verified in the room (ledger #3)
Verified G's stock_godverse/3962749/ (120 real records, Monster Robot Party crate 550, 2 x 2048^2, cell 256) in a fresh context — deliberately BEFORE the merge, so a contract failure would block it. It didn't. PASS — the contract holds; G re-emits nothing: - Resolves through the existing stockAdapter path via a base override (no C code change for the single-shop alpha). 120 items / 2 atlases / 8-of-8 stock meshes atlas-backed (real covers: peperecordings, DEEPCHILD, "39", mff FREAKS...). - Ceilings hold: 118 draws with real covers (<=350 law), pathOK, 0 carves. - Fail-soft holds (clean cache): missing atlas -> null -> parody (20 meshes, 110 draws); no adapter (?noassets shape) -> parody, zero fetch. 0 console errors. - G's index compliant: items[] sorted by id (my determinism ask honoured), provenance, uv in [0,1], 2 atlases = exactly the cap, cell_w/h harmless (C reads uv, never cell). CORRECTED MY OWN CEILING (LANE_C_PUB §7.2): I wrote "<=8 MB decoded" from an assumed ~16-item "typical shop". A real record shop is 120 records => 2 x 2048^2 ~= 32 MB, 4x my number. The structural rules held (<=2 atlases; 2048^2 for 60+ items — G landed on the cap); only the MB figure was wrong, because it described a shop that doesn't exist. New: <=2 atlases @<=2048^2, LRU = 1 shop's atlas set resident => <=32 MB peak (bounded; vs E's 181 MB unbounded today). Do NOT shrink the cell below 256 to save VRAM — the dig renders covers close up. G's ask #1 CONFIRMED and worse than reported (LANE_C_PUB §8 — C's spec, C's fix): stockpack keys _packs/_resolved by type alone, so base is ignored on a cache hit (measured: the 2nd preload returned the identical object). (1) two stocked shops collide; (2) it BREAKS FAIL-SOFT — an unstocked shop of a cached type inherits that crate instead of parody. Seam: key by type+base, per-shop preload on entry, LRU=1 + dispose; C consumes whatever identity field lands, C does not invent it. Two gaps block F's #7a, neither C's: the crate has no street (redhill_real absent; monsterrobot not in any shops[] — G's ask #2 to E/Fable), and interior_mode.js:192 pins base to assets/models/ (needs §8 + the identity field). Committed from a temp git worktree on main — the shared checkout stayed on lane-G-godverse (Fable's review) and G's branch keeps its disjoint namespace. Docs-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
84e0a1b764
commit
d2eb9df03f
@ -3,7 +3,54 @@
|
||||
*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 22) · owner: PROCITY-C · reviewer: Fable
|
||||
Last updated: 2026-07-16 (round 23) · owner: PROCITY-C · reviewer: Fable
|
||||
|
||||
---
|
||||
|
||||
## Update 2026-07-16 (round 23, v5.0-alpha THE FIRST REAL CRATE) — the crate in the room (ledger #3)
|
||||
|
||||
R23 §Lane C. **Verdict: the contract holds — G's atlas needs no re-emit.** Verified against G's
|
||||
`stock_godverse/3962749/` (120 real records from Monster Robot Party's DEEP HOUSE crate 550, 2 × 2048²,
|
||||
cell 256²) in a fresh context. Ran **before** Fable's merge deliberately — if the contract failed, that
|
||||
blocks the merge. It didn't.
|
||||
|
||||
**PASS — the first real crate renders in a PROCITY room:**
|
||||
- **Resolves through the existing `stockAdapter` path** via a base override — no C code change needed for
|
||||
the single-shop alpha. 120 items · 2 atlases · **8/8 stock meshes atlas-backed** (real covers). The
|
||||
sleeves are legible on screen: *peperecordings · DEEPCHILD · "39" · mff FREAKS · The Angels Instinct feat
|
||||
Charlie Ashcroft* — a real deep-house crate.
|
||||
- **Ceilings hold:** **118 draws** with real covers (≤350 law), `pathOK`, 0 carves.
|
||||
- **Fail-soft holds** (clean cache): missing atlas → `null` → parody (20 parody meshes, 110 draws); no
|
||||
adapter (the `?noassets` shape) → parody, zero fetch. **0 console errors.**
|
||||
- **G's index is compliant:** `items[]` sorted by id (my R22 determinism ask honoured), provenance present,
|
||||
`uv ⊂ [0,1]`, 2 atlases = exactly my cap, `cell_w/cell_h` harmless (C reads `uv`, never `cell`).
|
||||
|
||||
**I got a number wrong, and the first real data caught it (LANE_C_PUB §7.2 CORRECTED).** My R22 ceiling
|
||||
said "≤8 MB decoded" — derived from assuming a "typical shop" is ~16 items @1024². **A real record shop is
|
||||
120 records.** At the contract's own 256² cell that's 2 × 2048² ≈ **32 MB**, 4× my figure. The *structural*
|
||||
rules held (≤2 atlases; 2048² for 60+ items — G landed exactly on the cap); only the MB number was wrong,
|
||||
because it described a shop that doesn't exist. **Corrected:** ≤2 atlases/shop @≤2048², **LRU = 1 shop's
|
||||
atlas set resident ⇒ ≤32 MB peak** (still bounded; still far better than the 181 MB unbounded accretion E
|
||||
measured). And explicitly: **don't shrink the cell below 256² to save VRAM** — the dig shows a cover
|
||||
close-up; resolution is the one thing the player actually sees.
|
||||
|
||||
**G's ask #1 CONFIRMED — and worse than reported (LANE_C_PUB §8: C's spec, C's fix).** `stockpack.js` keys
|
||||
`_packs`/`_resolved` by **`type` alone**, so `base` is **ignored on a cache hit**. Measured:
|
||||
`preloadStockPack('record', {base:'…/3962749/'})` then `preloadStockPack('record', {base:'assets/models/'})`
|
||||
**returned the identical object**. Consequences: (1) two stocked shops collide — the 2nd serves the 1st's
|
||||
crate (blocks v5.0-beta, as G said); (2) **it breaks the fail-soft law** — an *unstocked* shop of a cached
|
||||
type inherits that crate instead of parody. The second is a correctness bug, not a mix-up. Seam spec
|
||||
published (cache key = `type + base`; per-shop preload on entry; LRU=1 + dispose; **C consumes whatever
|
||||
identity field lands — C does not invent it**). **C owns and lands it** — the §7 promise coming due.
|
||||
|
||||
**Two gaps block F's gate #7a (neither is C's; both flagged):** (1) **the crate has no street** —
|
||||
`redhill_real` doesn't exist and monsterrobot isn't in any town's `shops[]` (G's ask #2 → E/Fable);
|
||||
(2) the shell's `interior_mode.js:192` calls `getStockPack(shop.type)` with `base` fixed to
|
||||
`assets/models/`, so it can't reach a per-shop pack until §8's seam + the identity field land (C+F).
|
||||
|
||||
*Process note:* the shared tree was checked out on `lane-G-godverse` for Fable's review, so I committed
|
||||
these C docs from a temporary `git worktree` on `main` — the shared checkout was never touched, and G's
|
||||
branch keeps the disjoint namespace the two-studio merge law depends on.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
> (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.
|
||||
> **v5.0-alpha amendment (2026-07-16):** **§7.2's VRAM number corrected + §7.8 added** — G's first real
|
||||
> crate (120 records) proved my "≤8 MB" figure was derived from a wrong assumption, and the per-shop cache
|
||||
> seam is now specified for G+F. **G's R23 atlas needs no re-emit.** §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
|
||||
@ -242,10 +245,21 @@ worst rooms today are record 41 / book 58 / toy 57 draws against the ≤350 law;
|
||||
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).
|
||||
|
||||
> **⚠️ CORRECTED v5.0-alpha — measurement beat my assumption.** I wrote "≤8 MB decoded" by assuming a
|
||||
> "typical shop" is ~16 items @1024². **G's first real crate is 120 records** (Monster Robot Party, crate
|
||||
> 550) — a real record shop is nothing like 16 items. At the contract's own 256² cell that's 2 × 2048²
|
||||
> = **~32 MB decoded**, 4× my stated figure. The *structural* rules were right (≤2 atlases; 2048² for a
|
||||
> 60+ item shop) — only the MB number was wrong, because it was derived from a shop that doesn't exist.
|
||||
> **G's R23 atlas is compliant; no re-emit.** The corrected ceiling:
|
||||
|
||||
- **Per shop: ≤2 atlases, ≤2048² each** (unchanged — G's 120-item crate lands exactly on the cap).
|
||||
- **Resident: ONE shop's atlas set** (LRU = 1 shop, not 2) ⇒ **≤32 MB decoded peak**. Still bounded, and
|
||||
still far better than the **181 MB unbounded** accretion E measured today.
|
||||
- **≤1024² whenever the crate fits it** (≤64 items at 256²) — don't hand a 6-item shop a 2048².
|
||||
- Cell size is E/G's call: **C reads `uv`, never `cell`** (so 256², 176×256 portrait, etc. are all fine).
|
||||
Do **not** shrink the cell below 256² to save VRAM — the dig renders a cover close-up; resolution is the
|
||||
one thing the player actually sees.
|
||||
- **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**
|
||||
@ -274,4 +288,37 @@ a re-emit silently reshuffles every crate. Same discipline as E's byte-identical
|
||||
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.
|
||||
cover art real; prices real-or-seeded. *(v5.0-alpha: John amended this at tier 1 — real titles/artists ship
|
||||
in-house-green, flagged before public. Recorded in G's provenance; not C's to relax either way.)*
|
||||
|
||||
**8. The per-shop cache seam (v5.0-alpha — C's spec; G+F build to this). CONFIRMED BROKEN in R23.**
|
||||
G's ask #1 is real and I reproduced it. `stockpack.js` keys `_packs`/`_resolved` by **`type` alone**, and
|
||||
`preloadStockPack(type, {base})` **ignores `base` on a cache hit**. Measured (R23, fresh context):
|
||||
- `preloadStockPack('record', {base:'assets/stock_godverse/3962749/'})` → the 120-record godverse pack ✓
|
||||
- then `preloadStockPack('record', {base:'assets/models/'})` → **returned the identical object** ✗
|
||||
|
||||
Two consequences, the second worse than G's report:
|
||||
1. **Two stocked shops collide** — the 2nd silently serves the 1st shop's crate (blocks v5.0-beta).
|
||||
2. **It breaks the fail-soft law** — an *unstocked* shop of a cached type inherits that crate instead of
|
||||
falling back to parody. (On a clean cache fail-soft is intact: missing atlas → `null` → parody, 0 errors.
|
||||
The collision is what defeats it, so this is a correctness bug, not just a mix-up.)
|
||||
|
||||
**The seam (C owns it, C lands it):**
|
||||
- **Cache key = `type + base`** (equivalently a `packKey`; a godverse shop's key is its `stock_godverse/<godverse_id>/` base). `getStockPack` takes the same key.
|
||||
- **Resolution order** stays: explicit per-shop base → the type-pack base → `null` → parody.
|
||||
- **Per-shop preload on entry** (interior build/enter), **not** a boot-time preload of every shop.
|
||||
- **LRU = 1 shop's atlas set, disposed on eviction** (§7.2) — the load-bearing half of the §7 promise.
|
||||
- **Identity link:** a stocked shop must carry its pack pointer on the shop record (G's `godverse_id` →
|
||||
`stock_godverse/<id>/`). Not in the town cache today — G flagged it ("monsterrobot must be added to the
|
||||
godverse cache's `shops[]` as id 3962749"). C consumes whatever field lands; **C does not invent it.**
|
||||
|
||||
**9. R23 verification — the first real crate, in a room (ledger #3). PASS.**
|
||||
Measured against G's `3962749` atlas (120 real records, 2 × 2048², cell 256²) in a fresh context:
|
||||
- **Resolves through the existing `stockAdapter` path** via a base override — no C code change needed for
|
||||
the single-shop alpha. 120 items, 2 atlases, **8/8 stock meshes atlas-backed** (real covers, not parody).
|
||||
- **Ceilings hold:** **118 draws** with real covers (≤350 law); room `pathOK`, 0 carves.
|
||||
- **Fail-soft holds** (clean cache): missing atlas → `null` → parody (20 parody meshes, 110 draws, pathOK);
|
||||
no `stockAdapter` (the `?noassets` shape) → parody, zero fetch. **0 console errors** throughout.
|
||||
- **G's index is contract-compliant:** `items[]` sorted by id (my determinism ask honoured ✓), provenance
|
||||
present ✓, `uv ⊂ [0,1]` ✓, 2 atlases = the cap ✓, `cell_w/cell_h` harmless (C reads `uv`) ✓.
|
||||
- **Verdict: the contract holds. G re-emits nothing.** The only C-side work is §8's seam.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user