not-tonight/docs/VENUES.md
m3ultra 4caa901df2 Four venues, four rooms: the ladder stops being one map with different numbers
The venue ladder has always listed four venues in data/venues.ts, but they
shared ONE floor map and differed only by difficulty knobs — so a promotion you
survived a whole week for looked exactly like the room you had just left.

- venueMap.ts grows a FloorLayout contract (map + props + lights + posts +
  probes + palette) and the newGrid() primitives every room is painted with.
  Voltage stays IN venueMap rather than moving to layouts/, so the new rooms can
  import primitives from it without closing an import cycle.
- Three new rooms in src/scenes/floor/layouts/: The Royal (horseshoe public bar,
  pool room, pokies corner, trough + two cubicles, a beer garden that is plainly
  the nicest room in the pub, and a DJ "corner" that is a folding table because
  this pub never built a booth), Elevate (open-air rooftop — most of the grid is
  sky, the DJ is on an unwalled plinth, you arrive by lift), ROOM (concrete
  warehouse, pillars you path around, central booth, loading-dock smoking area,
  twelve lights in the whole venue).
- Nothing about a room is a module singleton any more. FloorView, sweep and
  FloorDemoScene take the layout; the door picks its street plate by venue id.
- FloorDemoScene's six hardcoded station spots (TAPS_SPOT, DECKS_SPOT, ...) were
  Voltage's tile coordinates. At four venues a hardcoded (47,3) puts the bar
  shift inside The Royal's pool room, so each layout now names its own stations
  and the scene reads them from there.
- tests/floor/layoutInvariants.ts is an executable rulebook: perimeter holds,
  every walkable tile reachable from the entry, anchors on walkable ground,
  posts not sealed (a post on a sealed tile freezes the player for the night —
  that has shipped twice), probes reachable, props on-grid. Proved against
  Voltage BEFORE the new rooms were authored against it.

Dev route #floor:<venueId> boots the floor straight into one room, because
otherwise seeing ROOM means surviving three weeks of the ladder.

Gate: lint clean, build clean, 821 tests passing (was 784).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 19:51:54 +10:00

8.0 KiB
Raw Blame History

NOT TONIGHT — the four venues

Written 2026-07-28. The venue ladder in src/data/venues.ts has always been four venues; up to now they shared ONE floor map and differed only by difficulty knobs. This document is the design contract for giving each its own room.

0. Why bother

Design §6 sells the ladder as promotion — survive a week, get a better door. But a promotion you cannot see is a number, not a reward. Walking into Elevate and finding The Royal's carpet under your feet undoes the fiction the whole run is built on. Each venue now has its own bar layout, its own dunnies, its own smoking area and its own DJ booth, because those four things are exactly what a bouncer actually learns about a room.

1. Shared contract (all four)

  • Grid is fixed at 80×45 tiles. Venues differ by ARRANGEMENT, not extent — the camera, minimap and bounds maths all key off MAP_W/MAP_H, and a per-venue grid size would be a refactor with no visible payoff. A small venue reads small by walling its unused grid to void, not by shrinking the array.
  • Every layout exports a FloorLayout: { id, map, props, lights, posts, probes }. Nothing else may be a module singleton — that was the old shape and it is what made four venues impossible.
  • Every layout must satisfy the same invariants (tests/floor/layouts.test.ts):
    1. every AnchorKind has ≥1 anchor, and every anchor is walkable;
    2. all walkable tiles are mutually reachable (flood fill), except sealed cubicle interiors, which must be reachable from their StallDef.door;
    3. every POSTS entry is walkable and has a walkable neighbour (a post on a sealed tile freezes the player for the night — this has shipped twice);
    4. every PROBES entry has a walkable tile within reach;
    5. no prop hangs off the grid.
  • Light signatures survive (SPACES.md §1): bar = amber, dance = pulsing pink on the real beat, DJ = deep blue, toilets = flickering green, smoking = cool blue, entry = venue pink. A venue may add ONE signature colour of its own — Elevate's skyline gold, ROOM's sodium orange — and no more, or the navigate-by-glow rule stops working.
  • Darkness stays the mechanic. No venue may be bright enough to scan from the doorway.

2. The Royal — "a dive with a dance floor"

Licensed 80 · regulars and punters · nobody checks anything.

A suburban Australian pub that had a dance floor bolted on in about 2004 and has not redecorated since. Patterned carpet, a horseshoe public bar, and the dance floor is plainly the least important thing in the building.

Space What's in it
Public bar (horseshoe, west) the long counter, taps, till, keg stack, a TV showing the footy, bar fridges
Pool room (north-west) two pool tables, cue rack, a dartboard on the wall
TAB / pokies corner (north-east) bank of poker machines, TAB screens, stools, its own miserable light
Bistro (centre-north) bistro tables, bain-marie counter, the meat-raffle drum
Dance floor (south-east) small, an afterthought, one mirror ball, a jukebox on the wall
DJ corner not a booth — a folding table with a controller, beside the dance floor
Dunnies (east) a stainless TROUGH, two cubicles (one out of order), one basin
Beer garden (south, open sky) picnic tables, umbrellas, patio heater, butt bin — the smoking area, and the nicest room in the pub

Light: warm amber everywhere, green cone over each pool table, the pokies' own sickly blue, and the beer garden cool blue. No pink except the dance corner.

3. Voltage — "valley institution"

Licensed 110 · the tuning baseline · the inspector drinks here.

This is the existing map and it does not change. It is tuned under the darkness sheet, its reachability is asserted, and every existing floor test targets it. It stays the default layout and the reference for the other three.

4. Elevate — "rooftop, small room, big opinions"

Licensed 70 · influencers and owner's mates · every second person is a VIP.

The whole venue is outdoors, which makes the rain a design element rather than a yard-only effect. Small footprint — a third of the grid is sky. You arrive by lift, not off the street, so the entry is a lobby.

Space What's in it
Lift lobby (west) lift doors, a rope line, the stamp podium, one mirror
Cocktail bar (north) short backlit bar, no taps — bottles and a champagne bucket
VIP booths (east) banquettes behind velvet rope posts, low tables
Dance floor (centre, small) it is a terrace with a dance floor, not a club
DJ plinth raised, open, no booth walls — the DJ is on display
Toilets (north-east) two unisex cubicles, marble basin, enormous mirror
Terrace edge (south + east) glass balustrade, planters, the city skyline beyond
Smoking the whole roof is open air; a designated corner with a standing ash urn and heat lamps

Light: warm amber bar, cool blue-white terrace, deep blue DJ, and the venue's own signature — skyline gold spilling from the city card beyond the glass.

5. ROOM — "no sign, no socials"

Licensed 60 · heads and chancers · the board is the law.

A concrete warehouse. No branding anywhere, because branding is how you get found. The sound system is the most expensive thing in the building by an order of magnitude and everything else is borrowed.

Space What's in it
Main floor concrete pillars, no booths, the crowd is the furniture
The stacks Funktion-One-style speaker towers + subs — huge, four corners
DJ booth low, central, facing the floor, no barrier — CDJs not turntables
Bar (west) a plywood plank on scaffolding, cans only, no taps, no till
Toilets (north-east) industrial, graffiti on every surface, three cubicles of which one works, a cracked basin, no mirror
Loading dock (south, open sky) roller door, pallets, a wheelie bin — this is the smoking area
Chill-out (north-west) two ruined couches under a single bulb
The board the rule board that rewrites itself (shuffleDressCode) — a physical prop by the entry

Light: almost none. Sodium orange over the loading dock (ROOM's signature), one flickering green fluoro in the dunnies, strobes on the floor, and the stacks' own power LEDs. This is the darkest venue in the game on purpose.

6. Prop vocabulary added for these rooms

Route per SPACES.md §"Prop pipeline": [F] = flux direct (flat things — signage, boards, screens, backdrops); [M] = product shot → TRELLIS.2 → Blender ortho render (things with volume). Rake follows the house rule — 60° low and wide, ~76° tall.

Venue Kinds
The Royal pokie[M76] tabBoard[F] bistroTable[M60] picnicTable[M60] trough[M70] keg[M76] dartboard[F] jukebox[M76] raffleDrum[M60] bainMarie[M60] tvSport[F] beerUmbrella[M80] ashtray[M60]
Elevate cocktailBar[M60] banquette[M60] ropePost[M76] planter[M60] balustrade[M76] djPlinth[M60] marbleSink[M70] ashUrn[M76] champBucket[M60] loungeChair[M60] liftDoor[F] skylineCard[F]
ROOM stackF1[M76] subBass[M60] plywoodBar[M60] rollerDoor[F] pallet[M60] wheelieBin[M76] oldCouch[M60] pillar[M76] ruleBoard[F] strobe[M76] smokeMachine[M60] cableSnake[M60] brokenBasin[M70] canStack[M60] cdj[M60]
Staff (set dressing, all venues) staffBartender staffDj staffGlassie staffSecurity — all [M76]

Staff figures are PROPS, not patrons. The procedural dolls stay exactly as they are: dollPlan draws the specific items the dress code convicts on, so replacing patrons with pre-rendered art would make the convictions invisible (recorded in LANEHANDOVER, FABLE-SOLO-23). A bartender who never moves is set dressing and carries no mechanical weight, which is why she can be a sprite.

Street plates (door scene, one per venue, [F], 640×176): street:royal street:elevate street:roomstreet:backdrop stays Voltage's.