Log inGet started
World

Blockbuster 767

Branchmain
Branchesmain
Commit8e9b87fcce

README.md

Screens

Every authored screen of BLOCKBUSTER 767, on the glass and driven. One instance, on mount_screens; it needs nothing else on that entity.

What it puts up

ScreenLayerWhat it carries
bb_hud20The wind-up HUD, the flight HUD, and the reduced readout that stays up through the wreck beat.
bb_card800The title card, the how-to-play card, the pause card, the wreck tally and the end card.

The trees are built by game.ui.cards and game.ui.hud, styled from game.ui.theme, and drawn with game.ui.art. Only this component holds state: which card is up, which row is lit, which line is printed, and the moves of the state machine that belong to presentation.

The three moves it owns

  • title → howto → opening. The first roundStart of a session puts the title card up; WIND IT UP moves to opening and hands the game to the director.
  • end → title. BACK TO THE BOX starts a fresh session and lands on the title card; WIND IT UP AGAIN starts one and goes straight back to the table.
  • A watchdog on opening. The opening flythrough belongs to the camera-director slice. If nothing hands the launcher over inside openingWatchdog seconds, this component moves opening → wind itself, rather than leaving the player looking at a camera move that never lands.

Everything else is somebody else's: the flight slice moves wind → flight and calls Game.endRound, and the scene entrypoint advances out of wreck.

Driving a card

game.input.console is activated the instant a card goes up and released the instant the last one comes down, and it stands down the whole flight group while it is live — so a stick held on a menu never also steers the toy.

Move the focusConfirmBackRestartResume
Keyboardarrows, W / SEnter, SpaceBackspaceREscape
Padleft stick, d-padsoutheastnorthstart
Pointer / fingerhover, tapclick or tap the rowtap BACKthe pause card's rowtap the row

All four move the SAME focus (game.ui.Focus), so the lit row is always the one that acts. A pointer only moves the focus when it CROSSES a row, so a mouse left resting somewhere cannot stop a pad walking the menu.

No control on the console map carries a touch binding, deliberately: a card draws its rows as real targets, and an on-screen Confirm button would be a second way to do what the card already offers.

Captions

Every line the Kid speaks is printed as well. game.audio.caption holds the current line; this component subscribes to it with Caption.on and takes Caption.claim("bb_screens") for as long as ANY card is up. That stands the sound slice's own bottom band down and carries the line inside the card instead, so a line spoken over the title, the pause card, the tally or the end card is read there rather than behind it. The claim is released — and the band comes back — the moment the last card comes down.

What it costs a frame

The card layer is decided every frame, because a card has to go up on the frame the state moves. The HUD is not: it is pushed at most twenty times a second, and only when a deliberately coarse reading of the telemetry has changed. A pushed tree is relaid out by the engine and the flight HUD is thirty-odd widgets, so pushing it every frame of a flight was one frame in ten over budget and a flicker the player could see. Screens:report().pushes counts what this component has actually handed the engine.

Fields

FieldDefaultWhat it decides
consoleMapgame.input.consoleThe controls every card answers to.
captionSeconds12How long the most recent spoken line stays printed on a card.
openingWatchdog9Seconds the opening flythrough may hold the game before the launcher is handed over anyway.

Reading it back

Screens:report() returns which card is up, which row is lit, the rows that card walks, whether the console map has the input, which screens are shown, the live caption, the game state and whether it is paused — the reading a test asserts against.