diff --git a/C-progress.md b/C-progress.md index bc1c784..fb64ef8 100644 --- a/C-progress.md +++ b/C-progress.md @@ -3,7 +3,32 @@ *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-14 (round 6) · owner: PROCITY-C · reviewer: Fable +Last updated: 2026-07-14 (round 7) · owner: PROCITY-C · reviewer: Fable + +--- + +## Update 2026-07-14 (round 7) — `?stock=real`: real GODVERSE sleeves in the crates + +Round-7 §Lane C: the `stockAdapter` seam built in v1 finally eats. Lane E's GODVERSE stock pack (parody- +transformed Discogs metadata + cover atlas) feeds record-shop bins + the dig riffle behind `?stock=real`. +- **Contract handshake** (task 1, unblocked E): confirmed E's index schema as-is in + [LANE_C_NOTES.md](docs/LANES/LANE_C_NOTES.md) — `{ items:[{id,title,artist,price,price_band,atlas,uv}] }`, + UV origin top-left (C flips V for WebGL), fail-soft, per-type packs. +- **New `stockpack.js`**: `preloadStockPack`/`getStockPack` (cached) + `makeStockAdapter`. Atlas texture + + material are shared/cached (like depot GLBs); sleeves are cover PLANEs sampling the atlas at each item's + baked UV → all real sleeves in a room **batch to one draw** (record: 59 draws). +- **Consumers**: `stock.js binFan` builds real cover planes (else parody canvas); `dig.js` riffles real + covers and the pull card shows **title / artist / $price / band**; `interiors.js` wires `opts.stock='real'` + through the seam (warn-once + parody fallback if the pack is absent); test page reads `?stock=real`. +- **Validated (sample 24-pack)**: determinism 0 fails/30, leak-free rooms AND real dig (0/0 over 25 cycles — + atlas shared, sleeve geo disposed), draws ≤139 all rooms (record 59), fail-soft on no-pack types (opshop + ok → parody), `?dig=1&stock=real` leak-free. Flag-off + `?noassets` untouched (procedural path byte-identical). +- Built against E's **staged sample** (real index format, synthetic covers); real Discogs covers drop in + unchanged when E gets the DB (external — John/Fable). Shot: [stock_real_r7.jpg](docs/shots/laneC/stock_real_r7.jpg). + +**→ F**: new smoke for your strict harness — `?stock=real` enter record shop + open dig → assert real +(non-parody) sleeves; the record bin's real sleeves are cover planes with `userData.isStock` on a shared +atlas material (drawSweep stays ≤350). Hook + adapter in LANE_C_NOTES. --- diff --git a/docs/LANES/LANE_C_NOTES.md b/docs/LANES/LANE_C_NOTES.md index 1f9bdbc..08ff003 100644 --- a/docs/LANES/LANE_C_NOTES.md +++ b/docs/LANES/LANE_C_NOTES.md @@ -1,5 +1,64 @@ # LANE C — cross-lane notes (PROCITY-C) +## → Lane F: `?stock=real` smoke for the strict harness (round-7 C1 landed) + +`?stock=real` is wired (record shops; book/toy fail-soft if E ships those packs). Smoke recipe: +- Preload once: `import { preloadStockPack } from interiors.js; await preloadStockPack('record')`. +- Boot `?stock=real`, enter a record shop, **assert real sleeves present**: a real sleeve is a `Mesh` + with `userData.isStock`, geometry `PlaneGeometry`/`BufferGeometry` (batched), on a shared **atlas** + material (`material.map` = the pack atlas, not a per-item canvas). Simplest assert: after build, + `let n=0; room.group.traverse(o=>{ if(o.userData?.isStock && o.material?.map) n++ }); assert n>0` — with + the pack loaded the record bins' sleeves batch to **one** atlas mesh (parody canvas would be ~6 card + meshes). Or open the dig (`?dig=1&stock=real`) and assert a pulled sleeve's panel title is a pack title. +- **Fail-soft**: pack missing → parody canvas + one `console.warn` (no throw). `?noassets` unaffected. +- **drawSweep still ≤350** with `?stock=real` (record 59 draws — the atlas batches all sleeves). + +## → Lane E: stock-pack contract CONFIRMED (round-7 C1) — build the real pack to this, unchanged + +Your proposed index schema is good — **confirmed as-is, no field changes**. Building `?stock=real` +against your staged 24-sleeve sample now (`web/assets/models/stock_record_{index.json,atlas_00.webp}`); +the real covers drop in unchanged. The contract C consumes: + +```jsonc +// stock__index.json (type ∈ record | book | toy ; record is the acceptance bar) +{ + "version": 1, + "atlas_px": 2048, + "cell": 256, // informational; C reads uv, not cell + "atlases": ["stock_record_atlas_00.webp", ...], // 1+; may be depot: or assets/models/ resolved + "items": [ + { "id": "rec_0000", + "title": "Neon Suburbs", // parody-transformed (no-real-trademarks law applies to metadata) + "artist": "Trev Wollemi", + "price": 39, // integer dollars — C shows "$39" + "price_band": "collector", // bargain|standard|collector|grail — C may tint the sticker + "atlas": "stock_record_atlas_00.webp", // which entry in `atlases` + "uv": [0.0, 0.0, 0.125, 0.125] } // [u0,v0,u1,v1] cover rect, ORIGIN TOP-LEFT + ] +} +``` + +Agreements / who-does-what: +- **UV origin is top-left (image-natural) — C flips V for WebGL** (`v_gl = 1 - v`). Keep your index + image-natural; the consumer handles the flip. (Sample verified against this.) +- **Resolution**: C loads `stock__index.json` from a base (default `assets/models/`, i.e. your + staged path — same-origin, works offline). Atlas filenames in the index resolve against the same base; + if you publish atlases to the depot, give me a `"depot": true` flag or depot-prefixed names and I'll + route through the `depot:` loader. For now the sample loads local. +- **Seeded pick per bin is mine** (same `shop.seed` → same crate contents). I only need *enough* items — + 24 repeats across bins (fine for testing); the 300 pack fixes variety. +- **Batching**: because every sleeve samples one shared atlas material (per-item UV baked into geometry), + all real sleeves in a room merge to **one draw** — the ≤350 law holds. Please keep it **one atlas per + pack** where you can (or few); each extra atlas = one more draw. +- **Fail-soft**: index/atlas missing or `?stock` off → parody canvas (warn once). `?noassets` untouched. +- **Per-type packs**: name them `stock_book_*`, `stock_toy_*` if you build them; I key by shop type and + fail-soft per type, so record-only is fine — book/toy are a bonus. + +You flagged needing a Postgres DSN (from John/Fable) to swap synthetic covers for real Discogs images — +that's external and **does not block my consumer**; ping me only if the schema needs to change. + + + ## → Lane F: interior ≤350-draw assertion for the harness (round-6 C1) C1 batching landed — worst room is now **313 draws GLB-on** / 152 GLB-off (was 1,245). The test page diff --git a/docs/shots/laneC/stock_real_r7.jpg b/docs/shots/laneC/stock_real_r7.jpg new file mode 100644 index 0000000..940319c Binary files /dev/null and b/docs/shots/laneC/stock_real_r7.jpg differ diff --git a/web/interior_test.html b/web/interior_test.html index 5b72666..654e169 100644 --- a/web/interior_test.html +++ b/web/interior_test.html @@ -69,9 +69,14 @@