# NOT TONIGHT — Spaces Plan

*How the game's two spaces grow from readable-but-abstract into places, using the
fleet's asset factories. Written 2026-07-20. Code contract: everything lands
behind data tables (`venueMap.PROPS` / `LIGHTS`) and a sprite drop-in convention —
generated art replaces placeholders with zero code changes.*

## 1. Design principles

1. **Darkness stays the mechanic.** Props read as silhouettes in ambient dark and
   resolve under the torch. Nothing may make the room bright enough to scan from
   the doorway.
2. **Navigate by light signature.** Each zone owns a colour of light, so the
   player orients by glow before geometry: bar = warm amber · dance floor =
   pulsing pink (on the actual beat) · DJ booth = deep blue · toilets =
   flickering green fluoro · smoking yard = cool rain-blue spill · entry/exit =
   venue pink. The torch is white; UV is purple. No other light sources.
3. **Props are data.** `PropDef { kind, tile pos, footprint, emissive? }` — the
   renderer prefers a generated texture (`gen:prop:<kind>`) and falls back to a
   procedural placeholder, so the game is complete TONIGHT and gets prettier as
   art lands.
4. **Spaces anticipate the role ladder** (design §6): the bar interior is laid
   out for a future bartender shift, the DJ booth for the DJ shift, the glassie
   station and smoking yard for floor loops that already have lanes speccing them.

## 2. The venue floor (80×45 tiles, one room + pockets)

```
┌──────────────────────────────────────────────────────────────────┐
│ N  ═ BAR ══════════ back-shelf glow          ┌─ DUNNIES ────────┐│
│    taps · till · glasses                     │ s1 s2 s3 s4      ││
│    ○○○○○○ stools                             │ sinks + mirror   ││
│                                              └───door───────────┘│
│ W                                                                 │
│ ┈entry┈  ┌ DANCE FLOOR (pulsing grid) ┐   ╔═ DJ BOOTH ╗    booths│
│ corridor │ speaker · · · · · speaker  │   ║ decks+mixer║        E│
│ posters  │  · · · disco ball · · ·    │   ║ (sealed)   ║   booths│
│ cloak    │ speaker · · · · · speaker  │   ╚════════════╝        │
│ glassie  └───────────────────────────┘                    booths│
│ station                                                          │
│    ▓ SMOKING YARD (open sky, rain) ▓   tables+candles     S     │
└────────▓ fence · butt bin ▓──────────────────────────────────────┘
```

Zone-by-zone (tile coords in `venueMap.ts`):

| Zone | What's there (props) | Light signature | Future role hook |
|---|---|---|---|
| **Bar** (north run) | back-bar shelf (emissive), 3 beer taps, till, glass stacks | steady amber pools along the shelf | Bartender shift: the serving lane between bar tiles and shelf is already unwalkable-to-patrons |
| **Dance floor** (centre) | 4 corner speaker stacks, disco ball (centre), floor grid cells | pink grid cells pulse ON `beat:tick`; ball throws a slow-rotating glint | DJ role reads crowd here |
| **DJ booth** (east of dance, sealed box facing the floor) | 2 decks + mixer (from the 90sDJsim gear GLBs!), booth monitor, lamp | deep blue wash + VU flicker | The DJ shift's playable pocket |
| **Booths** (south + east walls) | table per booth pair, candle | tiny warm candle pools | — |
| **Dunnies** (NE walled room) | sink row + mirror on west wall, hand dryer | green fluoro, FLICKERS (torch almost redundant inside — deliberate) | — |
| **Smoking yard** (SW walled pocket, open sky) | butt bin, milk crate seats, fence | cool blue outdoor spill + rain particles INSIDE the yard | FLOOR2's smoking loop (specced) |
| **Entry corridor** (west) | poster wall (3 art slots — MODELBEAST posters!), cloakroom window, stamp podium | venue-pink spill from the door | UV re-entry checks happen here |
| **Glassie station** (bar's west end alcove) | glass racks, tub trolley | dim amber | Glassie role's home base |

Sim impact: walkability only changes where NEW walls go (DJ booth box, yard
fence, sink row). All existing anchors keep working; reachability is asserted in
tests. The yard gets a `smoke` anchor upgrade so wanderers actually go out for one.

## 3. The door street (640×360 tableau)

Already reads well. Two upgrades, both drop-in images (no layout change):
1. **Backdrop plate** behind the existing rects: one wide pixel-art street wall
   (brick, posters, grime) — swaps in as `gen:street:backdrop` when generated.
2. **Kebab shop interior glow card** in its window + rotating poster art in two
   street frames (same poster slots as the entry corridor).

## 4. The sprite drop-in contract (how John's art lands)

- Drop processed PNGs in **`public/props/`** named `<kind>.png` and list them in
  **`public/props/manifest.json`** (`{"props": ["deck", "speaker", ...]}`).
- The floor loads the manifest at boot; anything listed replaces its placeholder
  (texture key `gen:prop:<kind>`). Missing = placeholder. No code changes.
- **`tools/props_import.py`** (PIL, runs anywhere with python3+PIL — ultra has it)
  takes raw generated images → target pixel size + palette quantise + transparent
  background → writes `public/props/` + updates the manifest:
  `python3 tools/props_import.py incoming/deck_raw.png deck`
- Target sizes are in the script (`TARGETS`): hero props 48–64 px, furniture
  24–32 px, small items 16 px. It refuses unknown kinds so typos can't ship.

## 5. GENERATION QUEUE — John's list (in priority order)

Pipelines: **[MB]** = MODELBEAST `flux_local` (params given) → drop raw output in
`art_incoming/`, run the import script (or hand me the raws — either works).
**[GLB]** = Blender ortho prerender of an existing fleet mesh (camera: orthographic,
top-down 90° for floor props / front 0° for the street, transparent film, ~512px,
neutral even lighting) → same import path.

| # | Item (kind) | Pipeline & source | Notes |
|---|---|---|---|
| 1 | `deck` | [GLB] `ultra:~/Documents/90sDJsim/web/world/models/gear/deck_t3_technics_sl_1200mk2.glb`, top-down | The hero. One render serves both booth decks |
| 2 | `mixer` | [GLB] same dir, `mixer.glb` (or the urei once landed), top-down | Sits between the decks |
| 3 | `speaker` | [GLB] 90sDJsim `models/props/` has boombox/speaker meshes; else [MB] prompt: "top-down view of a large black PA speaker stack, pixel art game sprite, dark background, viewed directly from above" 512×512 seed 4210 | 4 placements |
| 4 | `discoball` | [MB] "mirrored disco ball seen directly from above, glinting, pixel art sprite, black background" 512×512 seed 4211 | Centre of dance floor |
| 5 | `barShelf` | [MB] "top-down bar back-shelf with glowing bottles rows, amber light, pixel art sprite, dark" 1024×256 seed 4212 | Emissive — the amber source |
| 6 | `taps` | [MB] "row of three beer taps on a bar counter viewed from above, pixel art, dark bg" 256×256 seed 4213 | |
| 7 | `boothTable` | [MB] "small round pub table with two drinks seen from directly above, pixel art, dark bg" 256×256 seed 4214 | 6 placements |
| 8 | `sink` | [MB] "public bathroom sink row with mirror viewed from above, green fluorescent light, pixel art, dark" 512×256 seed 4215 | |
| 9 | `buttBin` + `crate` | [MB] one sheet: "outdoor smoking area props: cigarette butt bin and milk crate, top-down pixel art, dark bg" 512×256 seed 4216 | Yard dressing |
| 10 | `poster1..3` | [MB] three runs: "grimy nightclub gig poster, 90s Australian pub rock / techno rave / missing cat, pixel art, portrait" 256×384 seeds 4217-19 | FRONT view (posters hang on walls) — used at door + corridor |
| 11 | `street:backdrop` | [MB] "wide pixel art night street wall: dark brick, torn posters, graffiti, neon reflections, rain, front-on orthographic, game background" 1600×440 seed 4220 | The door scene plate. Biggest single visual win |
| 12 | `cloak` / `glassRack` | [MB] "cloakroom window with hanging jackets / metal glass rack with stacked pint glasses, top-down pixel art, dark" 256×256 seeds 4221-22 | Corridor + glassie station |
| 13 | `arcade` | [GLB] `m3ultra:~/Documents/procity/pipeline/_normalized/procity_fit_arcade_cabinet_01.glb`, top-down | Corner easter egg near entry |

**Ambition tier (later, not blocking):** pre-rendered patron sprite sheets from
the modular character kit + RIGROOM clips (`Searching_Pockets`, boxing pack,
`Leaning_Idle02_Smoking`, zombie stagger for maggots) — replaces the procedural
dolls entirely per docs/ASSETS.md §2. Wants its own session to set the
palette/density once.

*(flux params for all [MB] jobs: `model flux2-klein-4b, steps 4`; put "no text,
no lettering" in every prompt EXCEPT the posters, where mangled text reads as
authentic gig-poster grot.)*
