4.6 KiB
LANE C — INTERIORS (every door opens)
Prompt for Opus 4.8. You are working in
/Users/jing/Documents/PROCITY. Readdocs/CITY_SPEC.mdanddocs/RESEARCH.mdfirst, then the two sources you are porting:thriftgod/web/index.htmlbuildShop()(line ~1109+, archetypesSHOP_SHAPES, wall-slot system, seeded decor) and90sDJsim/web/world/fittings.js(parametric fittings kit — read it whole, it was written to be lifted). You ownweb/js/interiors/*andweb/interior_test.html. Do not touch other lanes' files. Plain ES modules, three.js fromweb/vendor/importmap, randomness viacore/prng.jsonly. Commit in small, described steps onmain.
Mission
The Vuntra move: every shop door opens into a unique, believable, seeded interior —
generated on demand in <50ms, byte-identical every revisit (shop.seed), themed by shop.type.
This lane is a standalone library + test page; Lane B wires it to real doors later via the
procity:enterShop / procity:exitShop events (contract in LANE_B).
Architecture
web/js/interiors/interiors.js— public API:
Pure function ofbuildInterior(shop, THREE) → { group, spawn:{x,z,ry}, exits:[{x,z,w, toStreet:true}], places:[…userData-tagged interactables], dispose() }shop(a CityPlan shop record + its lot dims). No global state.web/js/interiors/shell.js— the room shell: floor/walls/ceiling sized from the lot (lot.w × lot.d, storeys → ceiling height 3.2–4.5m), seeded from the 5 thriftgod archetypes (cosy / gallery / wide / hall / pokey) adapted to lot proportions, plus door/shopfront wall with real glazing (you can see a hint of street), back room doorway (blocked v1). Materials: seeded pick ofwall-*.jpgwallpapers,tex-carpet-*/tex-lino-*floors,tex-*counters — all already inweb/assets/gen/, all with flat-colour fallbacks.web/js/interiors/fittings.js— port 90sDJsim's kit and extend it. Needed set (see the registry's fittings mixes): record bins & crates, clothes racks, wall/cube/metal shelving, bookshelves, VHS aisle shelving, glass display case, counter + till, trestle tables, fridge, magazine rack, poster/art frames (art-*future), pegboard walls. Parametric primitives first; where a GLB upgrade exists use the manifest (see below) with primitive fallback.web/js/interiors/layout.js— the placer: per-archetype floor zones (window display / aisles / walls / counter-corner), the thriftgod shuffled wall-slot system so nothing overlaps, density from shop seed (some shops crammed, some sparse), guaranteed walkable path from door to counter (grid-mark occupied cells; verify connectivity with a flood fill — assert it).web/js/interiors/stock.js— v1 visual stock only: product boxes/sleeves/spines as canvas-texture blocks on shelves (steal the dig.js sleeve-canvas trick — coloured cardboard + price stickers). Real items are the content phase; leave astockAdapterhook:(shop, slotKind) => texture/meshso BaseGod data can plug in without touching layout code.- GLB upgrades: read
web/assets/manifest.jsonif present (Lane E ships it) mapping fitting ids → 3GOD depot files; promise-cached loader, placeholder-persists pattern. The test page must be fully usable with no manifest and no network. - Windows-from-street problem (Lane B fakes it): you own the inside-looking-out — a simple
backdrop plane beyond the glazing (street-ish gradient /
sky-*slice) sells it in v1.
Type theming (registry-driven)
Import SHOP_TYPES from core/registry.js; every type in CITY_SPEC's table gets a distinct
recipe (fittings mix, wallpaper bias, clutter level, counter position, signage-inside flavour).
A record shop must instantly read different from a toy shop from the doorway. Milk bar
counter faces the door; pawn shop is counter-forward with wall hooks; dept anchor is the
"grand hall" archetype with mixed sections.
Test page (web/interior_test.html)
Standalone: seed input, type dropdown, archetype override dropdown, "re-roll", first-person walk
inside (reuse PointerLock pattern), wireframe/occupancy-grid debug toggle, and a "50-room soak"
button that builds+disposes 50 seeded interiors and reports ms/room + leaked geometries
(renderer.info.memory before vs after — must return to baseline).
Acceptance
- Same seed twice → identical room (soak test asserts deep-equal on placement lists).
- All 9 types × 5 archetypes render sensibly (screenshot grid into
docs/shots/laneC/). - Build <50ms/room, dispose leak-free, flood-fill path door→counter always exists.
- Runs with zero assets (fallback colours) and zero network.