PROCITY/docs/LANES/LANE_C_INTERIORS.md
2026-07-14 10:46:40 +10:00

72 lines
4.6 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 C — INTERIORS (every door opens)
> **Prompt for Opus 4.8.** You are working in `/Users/jing/Documents/PROCITY`. Read
> `docs/CITY_SPEC.md` and `docs/RESEARCH.md` first, then the two sources you are porting:
> `thriftgod/web/index.html` `buildShop()` (line ~1109+, archetypes `SHOP_SHAPES`, wall-slot
> system, seeded decor) and `90sDJsim/web/world/fittings.js` (parametric fittings kit — read it
> whole, it was written to be lifted). You own `web/js/interiors/*` and `web/interior_test.html`.
> Do not touch other lanes' files. Plain ES modules, three.js from `web/vendor/` importmap,
> randomness via `core/prng.js` only. Commit in small, described steps on `main`.
## 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:
```js
buildInterior(shop, THREE) { group, spawn:{x,z,ry}, exits:[{x,z,w, toStreet:true}],
places:[…userData-tagged interactables], dispose() }
```
Pure function of `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.24.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 of `wall-*.jpg` wallpapers, `tex-carpet-*`/`tex-lino-*` floors,
`tex-*` counters all already in `web/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 a `stockAdapter` hook:
`(shop, slotKind) => texture/mesh` so BaseGod data can plug in without touching layout code.
- **GLB upgrades**: read `web/assets/manifest.json` if 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 doorcounter always exists.
- Runs with zero assets (fallback colours) and zero network.