Log inGet started
World

Blockbuster 767

Branchmain
Branchesmain
Commit8e9b87fcce

README.md

cards

Every full-screen card BLOCKBUSTER 767 puts between the player and the table.

local Cards = require("game.ui.cards")
ui.updateScreen("bb_card", Cards.title(Theme.metrics(), { focus = "bb_row_play", caption = nil }))
BuilderThe card
title(m, view)The toy, the logo, the tagline, WIND IT UP and HOW TO PLAY. Printed on a SEE-THROUGH backdrop over the real launcher and the untouched city, so the drawn skyline emblem comes off.
howto(m, view)The brief and the control table — one row per action, carrying the keyboard caps, the connected pad's own legends (Zin.gamepad.label, so A on an Xbox pad and Cross on a PlayStation one) and the touch control's name, plus a legend saying which colour is which device. view.showPlay is false when the card was opened over a pause card, where the only sensible move is back.
pause(m, view)Score, plane and towers so far, and the four things a paused player might want. Printed on a SEE-THROUGH backdrop, so the toy is still visible where it was left.
tally(m, view)The wreck beat's panel: which plane went down and why, the round's towers / blocks / off-table, what it scored and the running total. Not a menu — it plays and passes on its own, and it sits low so the resting airframe stays in frame above it.
endCard(m, view)The verdict, the stars, the final score, what is still owed for the next one, the session's counts, and the way back to the table or to the title. Also see-through, over the camera's slow swing across the wreckage. A star not earned is drawn in a dark socket with a lit rim rather than at half opacity on a ground it could not be told from.

Every builder is PURE: metrics in, a plain view table in, a widget tree out. Nothing here registers a screen, reads the session, activates a map or moves the state machine — Screens.component does all of that and hands the answer in. That split is what lets a card be rebuilt every frame the focus moves without any of the game noticing.

The shape rules

  • One column, centred, capped to m.cardW — so a 3:4 phone and a 21:9 monitor both get a readable measure rather than a stretched band.
  • Every size comes from Theme.metrics(), which reads the live screen.
  • Prose wraps against a container, never against the label. A label carrying both wrap and a width breaks to one glyph per line, and a column that CENTRES its children sizes them to their content, which leaves a label no definite width to wrap against and does the same. paragraph handles both.

The rows

Cards.row(m, id, label, hint, lit, delay) builds one focusable row, and its id is at once the widget id, the focus id and the callback id — so a pad's focus, a mouse's hover and a finger's tap can never disagree about which row they mean. The ids the component walks are bb_row_play, bb_row_howto, bb_row_back, bb_row_resume, bb_row_restart, bb_row_title and bb_row_again.