polish: scene nits — live-lens yard, square stacks, deck-clear billboard, two-layer lamps, flare reach, phone traffic and exposure

This commit is contained in:
2026-10-12 18:59:33 +03:00
parent 71465fa481
commit 3602eeb3d1
23 changed files with 671 additions and 73 deletions

View File

@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from 'vitest';
import { SceneResourceBag } from '@/scene/resources';
import { publishBillboard, billboardStops, type BillboardProject } from '@/journey/billboard-progress';
import {
BILLBOARD_DECK_CLEAR_Z,
BILLBOARD_TIMING,
BILLBOARD_Z_FROM,
BILLBOARD_Z_TO,
@@ -9,6 +10,7 @@ import {
billboardZ,
composeScreen,
createBillboard,
deckAhead,
SCREEN_ASPECT,
STANDING,
textureSize,
@@ -156,6 +158,23 @@ describe('billboard world', () => {
expect(board.mesh.visible).toBe(false);
});
it('holds down until the EXIT 05 deck has passed the camera, then rises', () => {
const board = createBillboard(new SceneResourceBag(), { mode: 'full', textureSize: 512, io: fakeIO().io });
// The deck comes down the road from the haze toward the camera (z ~25).
for (let z = -400; z < BILLBOARD_DECK_CLEAR_Z; z += 4) {
board.update(frame('infrastructure', null, { deckZ: z, deckExit: 'selected-builds' }));
expect(board.inspect().rise).toBe(0);
}
// Another chapter's deck, or no deck, never holds it.
expect(deckAhead({ deckZ: -80, deckExit: 'additional-work' })).toBe(false);
expect(deckAhead({ deckZ: null, deckExit: 'selected-builds' })).toBe(false);
const up = run(board, 10, frame('infrastructure', null, { deckZ: BILLBOARD_DECK_CLEAR_Z + 2, deckExit: 'selected-builds' }));
expect(up.at(-1)!.rise).toBe(1);
// Standing (reverse drive back under the deck): it stays up.
const back = run(board, 3, frame('infrastructure', null, { deckZ: -60, deckExit: 'selected-builds', direction: -1 }));
expect(back.at(-1)!.rise).toBe(1);
});
it('keeps the floods off while rising, then lights each project in order and reverses', async () => {
publishBillboard(PROJECTS, STOPS);
const board = createBillboard(new SceneResourceBag(), { mode: 'full', textureSize: 512, io: fakeIO().io });