From 6d2fc56bfb360e6d53241a14a1fd00a95b9e45fa Mon Sep 17 00:00:00 2001 From: type-two Date: Wed, 22 Jul 2026 02:28:48 +1000 Subject: [PATCH] =?UTF-8?q?Handover:=20FABLE-SOLO-12=20=E2=80=94=20three?= =?UTF-8?q?=20lifecycle=20fixes=20and=20a=20soak=20against=20the=20roster?= =?UTF-8?q?=20wave?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- LANEHANDOVER.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/LANEHANDOVER.md b/LANEHANDOVER.md index 5cbd1db..03ad7d0 100644 --- a/LANEHANDOVER.md +++ b/LANEHANDOVER.md @@ -1655,3 +1655,63 @@ collected $19, baggie pocketed with incident ✓ · walk-out at the entry anchor ### Note `entry` anchor is (72,360) — tile (4,22)-ish, NOT the exit tiles at x=1; the sweep walk-out and the night-mode exit both key off `VENUE.anchors.entry[0]`. + +--- + +## SESSION — FABLE-SOLO-12 · 2026-07-22 + +**Branch:** main (solo, Fable) · **Gate:** lint ✓ build ✓ test ✓ (735 tests, 49 files) +**Deployed:** https://monsterrobot.games/not-tonight/ (curl 200) + +This session ran ALONGSIDE the parallel session that landed the roster wave +(41e93d0..d4f8024). No feature work from me — I soak-tested, found three real +defects, fixed them, and re-verified the merged tree. + +### Fixed 1 — the dev route killed the door (main.ts, NightScene) +`showScene()` stopped `'Door'` (it was in the stop list) and then declined to +restart the already-active `'Night'`. Pressing **N** mid-night therefore left a +live Night driving a SHUTDOWN Door: an unplayable black screen with no way back. +`'Floor'` was not in the list at all, so it survived — the asymmetry is what made +it look like a launch race. Now only ROOT scenes route (`Roster/Night/Parade/ +FloorDemo/JuiceDemo`), and re-pressing a route key restarts the target, so N +means "fresh night". `NightScene.teardown()` now stops Door and Floor, making +real the ownership main.ts always claimed in a comment. + +### Fixed 2 — every floor-start shift booted INERT (NightScene) +`applyLocation()` moves flags but emits nothing; the initial call is +`applyLocation(role.startLoc)`. FloorDemoScene latches `present` when it binds +the night context — and now that the night preloads all 28 prop textures, the +floor's own loader finds nothing missing and binds SYNCHRONOUSLY, i.e. BEFORE +that delayedCall(0) runs. So `present` latched `false` for bartender, glassie +and DJ: floor visible, camera live, and every interaction dead. The audio filter +also stayed in door mode while you stood on the dancefloor. The night now emits +`night:phaseChange` + `audio:location` for the starting post. Verified all four +roles: bartender→taps, glassie→floor, dj→decks, door→door. + +### Fixed 3 — the floor carried last night into this one (FloorDemoScene) +Phaser reuses scene INSTANCES across restarts, so class-field initialisers run +once per GAME. A DJ shift left `djMode` set and the next night booted with +movement locked and the keyboard eaten; last night's `puddles` kept slipping +people through sprites Phaser had destroyed; `spotted`/`cutOffDealt`/`jointDealt` +marked fresh arrivals as already handled (patron ids restart with the run). +`resetNightState()` in `create()` now wipes all of it. NOTE: the roster wave's +own bar state (tabs/tips/orders/staffReadyAt) was already reset correctly in +bindNight — only the older floor state leaked. + +### Soak (frame-stepped, ~1.5h game time, zero errors) +Door object count flat (~70), floor objects track crowd, vibe oscillates 50→67→54 +(live pressure, not pinned). Night ended legitimately on AGGRO 97.8 after I +abandoned the rope all night and Kayden waved through 13 people including a +17-year-old — the fail narration is correct. + +### Verified of the roster wave +Roster board renders and routes; BARTENDER shift starts on the floor at the taps; +order → SERVE → pour meter → vibe +4.2 → `barServe` incident. Old saves still +load (GameState shape unchanged, `loadGame` validates `v===1` and falls back). + +### Harness note for future sessions +`window.game.loop.step()` does NOT advance real asset loading. A night that +preloads 28 textures needs real wall-clock time before Door/Floor launch — step, +then `await sleep(~900ms)`, then step again. Two "critical bugs" this session +were my own harness outrunning the loader; check `scene._queue` and +`load.totalToLoad` before believing a scene is stuck.