Lane B (Streetscape) round 14: v3.0 release — alpha-alias retirement + tour audit + queue_night hero (?gigs=1)
Release round: no new systems, no rng, goldens frozen (0x3fa36874 / gig 0x1f636349 both unmoved). Files: audio.js, venue.js, dbg.js (+ LANE_B_NOTES). Verified fresh Chromium, seed 20261990. - Alpha-alias readers dropped (debt #1, B first): audio.js venueGigState() loses the alias hop (g.venueShopId===id -> g.state); byVenue + clock fallback only. venue.js stateGetter() loses the bare-string arm (F passes gigState.byVenue since R13, confirmed index.html:379); seed = update(null). Verified live: byVenue {116:on,404:on,490:quiet} at NIGHT drives the marquee with no string arm; audio resolves gig-<genreKey> per venue with no alias hop. F is UNBLOCKED to delete the getters. - Bookmark/tour audit under ?gigs=1: all 19 bookmarks resolve, frame un-letterboxed, 0 page errors, <=300 draws. District venue-conversions hijacked none (night_neon->Video Regal, dig_real->Retro Groove). No pose fixes needed. (Orphan-chunk teleport inflates tris across sequential shots -- fresh counts <=153k; tram_stop's real ~293k is close-range Lane D GLB ped rigs, framing fine, not a venue block.) - queue_night bookmark added (dbg.js): John's release hero -- close 3/4 on the pub door at seg 5 ('on'), biased to the queue side; new poseForVenueQueue() recomputes venue.js frontage geometry. Frames marquee + window glow + streetlamp pools + the queue (spawned live by the shell loop; F's gig_shot.py drives it live -- verified by manually spawning D's VenueQueue: 2 punters at the door). - Poster-repetition call (debt #4): FINE, no ask to E -- 2 gigs tonight => 2 distinct designs (screenprint/Screaming Utes x7, xerox/The Dead Ringers x7); variety scales with venues playing. - Town-wide streetlamp pools: v3.1 candidate per Fable ruling (venue-scoped for v3.0; no code). -> Lane F: cross-lane alias sweep is CLEAN (no A/C/D/E reads it); only your own 20 tool lines in flags_check.py + gig_shot.py remain -- migrate to *Of(id)/venueShopIds[0] when you delete the gig_state.js:141-151 getters + the CITY_SPEC alias line (with A). -> Lane A (now gates John's hero-shot poster): buildPosters item 1 still seats each venue's own frontage poster on local -Z (back wall, 15.9m from the +Z street facade). Flip to +sin,+cos and it seats by the door -- in the existing queue_night frame, no pose change. Per "don't touch world code," B did not work around it. Re-flagged from R13. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
62e38c5df8
commit
eee60e05a5
@ -1,5 +1,76 @@
|
||||
# LANE B — NOTES (measured)
|
||||
|
||||
## Round 14 (Fable's ROUND14 → Lane B) — v3.0 RELEASE: alias retirement + the tour audit
|
||||
|
||||
Release round — no new systems. Three B files touched (`audio.js`, `venue.js`, `dbg.js`); no world
|
||||
geometry, no rng, goldens frozen (`0x3fa36874` synthetic, `0x1f636349` gig — neither moved). Verified
|
||||
fresh Chromium, seed 20261990, `?gigs=1`.
|
||||
|
||||
### 1. Alpha-alias readers dropped (debt #1 — B first; **F unblocked**)
|
||||
The R12 `window.PROCITY.gigs` scalar alias (`.state/.on/.venueShopId/.cover/.paid/…`) is retired this
|
||||
round. B's readers removed:
|
||||
- **`audio.js`** `venueGigState()` — dropped the alias hop (`g.venueShopId === shopId → g.state`).
|
||||
Now byVenue-only + the clock fallback: `g.byVenue[id]` → else `plan.gigs` night-0 vs the segment.
|
||||
- **`venue.js`** `stateGetter()` — dropped the bare-string arm; reads `gigStates.byVenue || gigStates`
|
||||
(F passes `gigState.byVenue`, confirmed at `index.html:379`). Seed call is now `update(null)`.
|
||||
|
||||
Verified live: F's `gigState.byVenue` reads `{116:'on', 404:'on', 490:'quiet'}` at NIGHT (pub + RSL
|
||||
playing, band_room dark); passing it to `venue.update()` lights the marquee with **no string arm**, and
|
||||
`audio.js` resolves each venue's `gig-<genreKey>` with **no alias hop**. Audio engine loads `live`.
|
||||
|
||||
**→ Lane F (you can now delete the alias):** an alias-surface sweep (all of `web/js/**`, `index.html`,
|
||||
`tools/**`) confirms **CROSS-LANE CLEAN** — no A/C/D/E file reads the scalar alias (interior_mode.js
|
||||
uses `onOf()/gigOf()`; sim.js uses shell-driven `setGig`). The only remaining alias readers are **your
|
||||
own 20 lines** in `tools/flags_check.py` + `tools/qa/gig_shot.py` (`.venueShopId`×12 → `venueShopIds[0]`
|
||||
or an explicit id; `.state`×5 → `stateOf(id)`; `.cover`×2 → `coverOf(id)`; `.bandName`×3 →
|
||||
`bandNameOf(id)`; `gig_shot.py:81` already prefers `stateOf(id)`). Delete the alias getters at
|
||||
`gig_state.js:141–151` + migrate those tool lines in the same commit; `!!P.gigs` existence checks keep
|
||||
working (the per-venue machine still exists). CITY_SPEC §v3 runtime block loses the alias line (with A).
|
||||
|
||||
### 2. Bookmark / tour audit under `?gigs=1` — **all clean, no pose fixes**
|
||||
All 19 bookmarks (16 v2 + `venue_night` + `district_posters` + new `queue_night`) resolve, frame
|
||||
**un-letterboxed**, **0 page errors**, ≤300 draws. The district's in-place venue conversions hijacked
|
||||
**no** bookmark: `night_neon`→"Video Regal" (openLate is never converted), `dig_real`→"Retro Groove"
|
||||
(a real record shop survives — multiple per type). Framing eyeballed clean on the tour spread:
|
||||
`street_noon`, `venue_night`, `queue_night`, `tram_stop`, `district_posters`, `night_neon`. **No dbg.js
|
||||
pose changes were needed** beyond adding `queue_night`.
|
||||
- **Measurement gotcha (re-confirmed):** `DBG.shot` teleports, so shooting many bookmarks in sequence
|
||||
leaves orphan chunks that inflate tris on later shots (saw 238k on `patronage_door`; **42k** on a
|
||||
fresh load / shoot-twice-to-settle). Shoot from a clean load, or twice, for the true per-frame count.
|
||||
- **Observation → Lane D / Fable (not a Lane B fix):** `tram_stop` is a stable **~293k tris** — real,
|
||||
from close-range full-detail GLB ped rigs on the footpath (framing is fine). It's not a venue block
|
||||
(F's tri gate measures at the venue block, ~64k), so it likely doesn't trip the gate, but it exceeds
|
||||
the 200k reference for a tour shot; worth a look if a close ped shot lands in the release set.
|
||||
|
||||
### 3. `queue_night` — John's release hero (`dbg.js`)
|
||||
New bookmark `queue_night` (seg 5 / NIGHT / 'on'): a close 3/4 on the pub door, biased to the venue's
|
||||
`+right` (the queue side). New `poseForVenueQueue()` recomputes venue.js's frontage geometry from the
|
||||
pub lot: `DIST 7 m` out on the street, `SIDE = mw/2 + 2.2 m` to the queue side, eye 2.2 m, looking at
|
||||
the door lifted to y2.7 (catches the marquee). Verified: frames marquee + window glow + streetlamp
|
||||
pools + the queue. **The queue is spawned by the shell's live rAF loop** (`index.html:383` builds D's
|
||||
`VenueQueue` on `openOf(id)`), so F's `gig_shot.py` must drive it **live** (the automation rAF is
|
||||
throttled — I confirmed the pose + D's line by manually spawning `VenueQueue` at the pub queueZone: 2
|
||||
punters seat at the door, facing it).
|
||||
- **→ Lane A (blocks the hero's poster):** `queue_night` frames door + marquee + queue, but **no poster
|
||||
lands in the close frame** — the pub's own-frontage poster is still on A's local **−Z** (the BACK
|
||||
wall, `gigs.js buildPosters` item 1 `-sin,-cos`; measured 15.9 m from the +Z street facade), and the
|
||||
nearest spine poster is 53 m away. Per Fable's "fix poses, don't touch world code," B did **not**
|
||||
work around it. **Flip item 1 to `+sin,+cos`** and the frontage poster seats by the door — in the
|
||||
existing `queue_night` frame with no pose change. (Re-flagged from R13; now it gates John's hero shot.)
|
||||
|
||||
### 4. Poster-repetition call (debt #4) — **FINE, no ask to E**
|
||||
Tonight's 14 posters carry **2 distinct designs** (Screaming Utes / screenprint ×7, The Dead Ringers /
|
||||
xerox ×7 — different skins, different bands). Variety = number of venues playing tonight (one seeded
|
||||
skin per gigId), so a spine run reads as two real band bills, not a repeat. Only a town where a single
|
||||
gig plays everywhere would look monotonous (rare, and reads as "a residency"). No new templates needed.
|
||||
|
||||
### 5. Town-wide streetlamp pools — v3.1 candidate (Fable ruling, no code)
|
||||
Fable ruled the night pools **stay venue-scoped for v3.0** (town-wide needs always-on `furniture.js`
|
||||
changes that fight flags-off parity in release week; venue blocks read fine — `venue_night` proves it).
|
||||
Parked here as a **v3.1 candidate** alongside wind sway and bench-sit loiter. No R14 code.
|
||||
|
||||
---
|
||||
|
||||
## Round 13 (Fable's ROUND13 → Lane B) — the district reads by night (`?gigs=1`, v3.0-beta)
|
||||
|
||||
Four B pieces, all gig-gated (flags-off byte-identical, verified). Files: `venue.js` (rewrite),
|
||||
|
||||
@ -205,15 +205,13 @@ export function createAudioEngine(PROCITY, { noassets = false, mute = false } =
|
||||
const lot = pub && (PROCITY.plan?.lots || []).find((l) => l.id === pub.lot);
|
||||
if (lot) venues.push({ shop: pub, lot, genreKey: pub.genreKey || 'pubrock' });
|
||||
}
|
||||
// Per-venue gig state for the muffled spill, robust across Lane F's alpha→district transition:
|
||||
// 1. F R13 per-venue map window.PROCITY.gigs.byVenue[id].state
|
||||
// 2. alpha alias window.PROCITY.gigs is the single machine → its state for its venueShopId
|
||||
// 3. clock fallback plan.gigs (night 0) vs the current segment (works before/without F)
|
||||
// Per-venue gig state for the muffled spill (R14: the R12 alpha alias hop is retired):
|
||||
// 1. F's per-venue map window.PROCITY.gigs.byVenue[id] (the canonical surface since R13)
|
||||
// 2. clock fallback plan.gigs (night 0) vs the current segment (works before F wires / headless)
|
||||
// Returns null only when there is no gig layer at all (flags-off ⇒ byte-identical, no spill).
|
||||
function venueGigState(shopId) {
|
||||
const g = PROCITY.gigs;
|
||||
if (g && g.byVenue) { const e = g.byVenue[shopId]; if (e) return typeof e === 'string' ? e : (e.state || 'quiet'); }
|
||||
if (g && g.venueShopId === shopId && typeof g.state === 'string') return g.state;
|
||||
const gigs = PROCITY.plan?.gigs; if (!gigs || !gigs.length) return null;
|
||||
const ton = gigs.find((x) => x.night === 0 && x.venueShopId === shopId);
|
||||
if (!ton) return 'quiet'; // dark tonight — reads true
|
||||
|
||||
@ -137,6 +137,25 @@ export function installDBG(deps) {
|
||||
|| (plan.shops || []).find((s) => s.type === 'pub');
|
||||
return shop ? poseForShop(shop, dist) : null;
|
||||
};
|
||||
// John's release hero: a CLOSE 3/4 on the pub door during doors/on, biased to the venue's +right
|
||||
// (the queue side) so punters' faces read and a verge poster enters frame. The queue + posters are
|
||||
// spawned by the live shell loop when the venue opens (seg 5 = NIGHT / 'on'), so F drives this shot
|
||||
// live; this just frames the door + marquee + queue zone. Geometry mirrors venue.js's frontage.
|
||||
const poseForVenueQueue = () => {
|
||||
const vs = venueShops();
|
||||
const shop = vs.find((s) => (s.venueKind || s.type) === 'pub') || vs[0]
|
||||
|| (plan.shops || []).find((s) => s.type === 'pub');
|
||||
const lot = shop && lotOf(shop); if (!lot) return null;
|
||||
const ry = lot.ry || 0, fx = Math.sin(ry), fz = Math.cos(ry), rx = Math.cos(ry), rz = -Math.sin(ry);
|
||||
const w = lot.w || 8, d = lot.d || 10;
|
||||
const cx = lot.x + fx * (d / 2), cz = lot.z + fz * (d / 2); // door centre on the street (venue.js frontage)
|
||||
const mw = Math.min(w * 0.92, 6.5); // marquee width (queue head ~ +right of it)
|
||||
const DIST = 7.0, SIDE = mw * 0.5 + 2.2, EYE = 2.2; // close standoff, biased to the queue side
|
||||
return {
|
||||
pos: [cx + fx * DIST + rx * SIDE, EYE, cz + fz * DIST + rz * SIDE],
|
||||
look: [cx + rx * (mw * 0.30), 2.7, cz + rz * (mw * 0.30)], // door, lifted to catch the marquee
|
||||
};
|
||||
};
|
||||
|
||||
// Named bookmarks (LANE_F_NOTES §4). seg = day segment index (0 DAWN … 5 NIGHT).
|
||||
// Predicates cover both Lane A's taxonomy (dept/stall/record/…) and the fixture's; each falls back
|
||||
@ -164,6 +183,7 @@ export function installDBG(deps) {
|
||||
// ── v3 gig district (round 13, ?gigs=1): the street money shots F scripts via tools/qa/gig_shot.py ──
|
||||
venue_night: { seg: 5, resolve: () => poseForVenue('pub', 13) || streetViewPose(['main']) }, // ?gigs=1 — lit pub frontage + streetlamp pools + queue + posters at night
|
||||
district_posters: { seg: 5, resolve: () => streetViewPose(['main']) }, // ?gigs=1 — the spine at night: poster poles + lit venue frontages receding
|
||||
queue_night: { seg: 5, resolve: () => poseForVenueQueue() || poseForVenue('pub', 11) || streetViewPose(['main']) }, // ?gigs=1 — John's hero: close on the pub door at 'on', queue + marquee + poster, punters facing the door
|
||||
};
|
||||
|
||||
const DBG = {
|
||||
|
||||
@ -185,13 +185,13 @@ export function createVenuePresentation(plan, skins, scene, { assetBase = 'asset
|
||||
|
||||
scene.add(group);
|
||||
|
||||
// ── per-venue state → frontage glow. Accepts F's per-venue map { [venueShopId]: state }, a Map, an
|
||||
// { byVenue } wrapper, OR a bare state string (alpha compat → the primary pub). Idempotent; the shell
|
||||
// ── per-venue state → frontage glow. F passes its per-venue map `gigState.byVenue`
|
||||
// ({ [venueShopId]: 'quiet'|'doors'|'on'|'done' }); a Map or a { byVenue } wrapper are also accepted.
|
||||
// (R14: the R12 alpha bare-string arm is retired — F wires the map since R13.) Idempotent; the shell
|
||||
// calls it every street frame, so pool/glow ramps and the night baseline lerp here. ────────────────
|
||||
function stateGetter(gigStates) {
|
||||
if (gigStates == null) return () => 'quiet';
|
||||
if (typeof gigStates === 'string') return (id) => (id === primaryId ? gigStates : 'quiet');
|
||||
const map = gigStates.byVenue || gigStates;
|
||||
const map = gigStates.byVenue || gigStates; // F passes gigState.byVenue (per-venue map)
|
||||
return (id) => {
|
||||
const v = map instanceof Map ? map.get(id) : map[id];
|
||||
if (v == null) return 'quiet';
|
||||
@ -225,7 +225,7 @@ export function createVenuePresentation(plan, skins, scene, { assetBase = 'asset
|
||||
if (poolMesh) poolMesh.visible = poolMat.opacity > 0.01;
|
||||
}
|
||||
}
|
||||
update('quiet');
|
||||
update(null); // seed: no gig states yet → every venue quiet (frontage dark, pools follow night)
|
||||
|
||||
function dispose() {
|
||||
for (const d of disposables) d.dispose && d.dispose();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user