PROCITY/docs/LANES/LANE_C_PUB.md
m3ultra 05e020e3b8 Lane C: round-12 pub venue — archetype + watchPoints + audio.gigKey (?gigs=1)
v3.0-alpha band room. New pub recipe (venue:true): stage + PA + amps at the back wall (new stage/paSpeaker/ampStack fittings, GLB slots stage/pa_speaker/amp for E), bar counter (keeper), sticky carpet, blocked back door = green room.

buildInterior returns for venues: room.watchPoints[] (6-8 seeded audience poses {x,z,ry,dance} facing the stage, dance ~1/3, counter.stand ry convention); room.stage {x,z,w,d,deckY,frontZ,bandPoses[3]} for Lane D's band; room.audio.gigKey ('gig-'+genreKey) set when Lane F passes opts.gig.

Flags-off byte-identical: venue code runs only for recipe.venue on its own seed sub-streams; non-pub rooms have watchPoints:[], stage:null, unchanged placement/audio.

Verified: 40-seed pub sweep (0 throws/carves/path-fails, 8 watchPoints, dance 0.38) + 60-room mixed soak (0 det/path fails, leak geo0/tex0, worst 19ms). Non-pub unchanged. Interface for D/F: docs/LANES/LANE_C_PUB.md. scaffold + manifest green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 18:59:48 +10:00

56 lines
3.5 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 — pub venue interface (round 12, v3.0-alpha) → for Lane D + Lane F
*PROCITY-C, 2026-07-15. R12 §Lane C. The band room ships behind `?gigs=1` (A only emits `pub` shops
when the flag is on). Interface published here + in this commit's code; non-pub rooms are byte-identical
(the venue code only runs for `recipe.venue`, on its own seed sub-streams). Verified: 40-seed pub sweep +
60-room mixed soak — 0 throws · 0 carves · 0 path-fails · 0 determinism-fails · leak geo0/tex0 · worst 19 ms.*
## What `buildInterior` returns for a pub (type `'pub'`)
Everything below is **pure data on the return** (room-local coords, `counter.stand` ry convention:
rig-front = local Z), so Lane D drops rigs straight in and Lane F reads state — no new lifecycle.
### `room.stage` — the band stage (null for non-venues)
```js
room.stage = {
x, z, // deck centre (against the back wall)
w, d, // deck size (m)
deckY, // top surface height (m) — band rigs stand at y = deckY
frontZ, // z of the deck lip (the crowd stands in front of this, +Z)
bandPoses: [ { x, z, ry, role } ×3 ], // guitar / vocal / bass, across the deck front, facing the crowd (ry=π → +Z)
}
```
**Lane D:** put the 3-piece band at `bandPoses` (lift to `y = deckY`); `role` hints instrument. Drummer
can sit up-stage on the riser (there's a raised riser at deck-centre-back) — your call, C just gives 3 front poses.
Instruments = E's GLBs when present, primitives otherwise (asset law).
### `room.watchPoints` — the audience (empty [] for non-venues)
```js
room.watchPoints = [ { x, z, ry, dance, slotIndex } ] // 6..8 seeded floor poses, all facing the stage centre
```
- `dance` is seeded **~⅓ true** ("a bit of both"). **Lane D:** `dance:false` → stand-and-watch idle
(subtle weight-shift); `dance:true` → bob/sway/step loop with a **seeded phase offset** so the crowd
doesn't metronome (use `slotIndex` or the pose coords to derive the phase).
- Every point is walkable, reachable from the door, and clear of the keeper stand, browse points, and the
stage/PA footprint. Deterministic per shop.seed. Crowd cap = `watchPoints.length` (F's smoke asserts ≤).
### `room.counter` / keeper — unchanged
The bar is a normal counter; the **barkeep is just a keeper** at `room.counter.stand` (existing R9 seam).
### `room.audio.gigKey` — the live bed
`room.audio = { musicKey, toneKey, gigKey? }`. **Lane F** passes gig state via `opts.gig` to `buildInterior`:
```js
buildInterior(pubShop, THREE, { gig: { on: true, genreKey: 'pubrock' } })
// → room.audio.gigKey === 'gig-pubrock' (gigKey = 'gig-' + genreKey)
```
- `gigKey` is present **only when a gig is on**. A quiet-night pub has no `opts.gig` → normal interior
(`toneKey` room-tone + maybe the seeded radio `musicKey`).
- **Prefer `gigKey` over `musicKey`** while the gig plays: `play(room.audio.gigKey || room.audio.musicKey)`.
- **Lane E:** please name the pub-rock live bed **`gig-pubrock`** in `manifest.audio` (music or a `gig`
section) so the key resolves; missing key → silence (audio law), band still visible.
## The archetype (C-owned, FYI)
`pub` recipe (`theme.js`, `venue:true`): stage + PA + amps at the back wall, bar counter (`corner`),
sticky-carpet floor, pub tables + bar-back shelf against the walls, the blocked back doorway doubles as
the **green room**. Primitive stage/PA/amp fittings today with **GLB slots for Lane E**: `stage`,
`pa_speaker`, `amp` (house GLB law; primitive fallback holds — a gig with no GLBs is still a gig).