# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# lines
Everything the Kid says — the child whose playroom this is and whose toys these
are, narrating their own game.
One speaker, sixteen lines, grouped by `cue`: `title`, `wind1` / `wind2` /
`wind3`, `launch`, `topple`, `wreck`, and `end0` … `end3` for the star rating
the session lands on. Where a cue has several lines, `SoundDirector` picks one
and avoids the one it played last.
Each line carries its `text` and a `hold` — the seconds the caption stays up
when there is no clip to time it against. When there IS a clip, the caption
runs for the delivery's own length, which `game/audio/voicecache.module`
records.
**A line is spoken AND written.** `game/audio/voicebake.luau` buys the delivery
from `audio_gen.speech` exactly once and caches it as
`game/audio/voice/<id>.soundClip`; `SoundDirector` puts the text on screen at
the same moment through `game.audio.caption`. A muted player, a noisy room and
a generation that failed all leave the line intact.
Adding a line: write it here, then
```
execute { file = "/zero/source/game/audio/voicebake.luau", args = { ids = { "your_id" } } }
```
Speech is credit-metered. The bake skips every line that already has a clip, so
running it again costs nothing.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# rules
The cross-slice constants of BLOCKBUSTER 767 — read-only, and the contract
between any two parts of the game that have to agree on a number.
- `TABLE` — where the play surface is and where its edges are.
- `LAUNCH` — the launcher's position, how far the heading and elevation trim,
and the wind band: how long a notch takes, how many there are, and what the
red zone past the last one costs.
- `CITY` — the band of table the skyline stands in, its seed, and the landmarks.
- `PHYS` — masses, speed caps, the debris governor, the settle threshold and
the margin a measured joint break force is multiplied by.
- `SCORE` — what a shoved block, a toppled tower and a block off the table pay,
the chain window, the landmark and called-shot multipliers, and the star
thresholds.
- `SESSION` — three planes, the round clock, the rest and wreck beats.
- `STATES` / `EVENTS` — the only state names and event names the game uses; a
typo in either raises at the call rather than going quietly nowhere.
- `LAYOUT` — the bands every screen anchors into, as shares of the viewport.
Units are metres, kilograms and seconds. The table top is `y = 0`; `+Z` is
downrange, so the plane launches at `LAUNCH.z` and flies toward the city.
A number only one slice reads lives in that slice's own files, not here.
Consumed by every slice.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# theme
The look of BLOCKBUSTER 767's screens, in one place: the palette, the
typefaces, the metrics every screen sizes itself from, and the style fragments
the cards share.
```lua
local Theme = require("game.ui.theme")
local m = Theme.metrics()
{ type = "label", style = { fontSize = m.fs.title, fontFamily = Theme.font.display, color = Theme.color.cream } }
```
## The metrics rule
Nothing is a pixel number chosen for one screen. `Theme.metrics()` reads the
live `ui.screenSize()` and derives everything from it:
- **Type and rhythm** are a share of the SHORTER side, so a phone held either
way and a television read the same.
- **Both are additionally capped against the HEIGHT.** A card is a column, and a
wide screen is also a short one; without that cap the card that fits a 3:4
frame runs off the bottom of a 16:9 one.
- **The two big pictures** — `hero` (the toy on a card) and `strip` (the skyline
along its foot) — are budgeted straight out of the height they have to fit in.
- `cardW` caps a card to a readable single column instead of letting it stretch
across a wide monitor.
`Theme.metricsFor(w, h)` computes the same table for a shape the engine is not
currently running at — which is how a card is laid out and looked at for a
screen other than the one in front of you.
## The palette
Warm shadow, painted wood, poster paint on the toy, crayon accents, and the gold
of a sticker star. `Theme.color` names them; `Theme.font` names the four voices
(a poster face for the logo, a heavy face for headings, a plain face for reading,
a mono for numbers, and the round childlike face the Kid speaks in).
## The fragments
`cardBackdrop` (the playroom wash a card is printed on; its `see` argument is
the share of the ROOM that shows through, and the scrim's opacity is `1 - see`),
`panel` (a raised surface with a lit top rim), `row` (a menu row at rest or with
the focus on it), `chip` (the small rounded plastic label a keycap, a pad glyph
and a touch hint are all made of), `stat` (a number with its name under it), and
the three motions: `enterDrop`, `enterRise`, `pulse`.
**Nothing here animates for ever, and `pulse` breathes on opacity alone.** A
keyframe that animates `transform: scale` re-measures the widget's box every
frame, which relays out the whole tree it sits in; two HUD widgets each held one
of those permanently and one frame in ten was over budget because of it.
`pulse(iterations)` counts — eight breaths by default — so even the opacity
animation ends.
**No entrance starts from nothing.** An entrance holds its first keyframe until
its delay elapses and the UI clock is the game clock, so a card opened while
something is holding `engine.timeScale` down would sit on that first frame.
They start dimmed and slightly displaced instead, so the worst a stalled clock
can do is leave a card looking a shade soft.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# caption
The written form of everything the Kid says, so a spoken line survives a muted
player, a noisy room and a failed generation.
`SoundDirector` writes; anything that draws reads.
```lua
local Caption = require("game.audio.caption")
local now = Caption.current() -- { id, text, remaining, duration } or nil
local off = Caption.on(function(shown) ... end) -- every new line, and nil on clear
```
`SoundDirector` draws the words itself, in a band above the bottom control
band, laid out from the live `ui.screenSize()`. A screen that would rather
carry the line inside its own composed card takes the job:
```lua
Caption.claim("bb_screens") -- SoundDirector's band stands down
Caption.release() -- hand it back
```
Time is handed in rather than read: `Caption.tick(dt)` is called once a frame
by `SoundDirector`, so a caption follows the game's clock and holds still while
the game is paused.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# voicecache
How long the Kid's delivery of each line runs, in milliseconds.
`SoundDirector` reads this to decide how long a spoken line's caption stays on
screen: the printed words and the voice come down together, so a line that
takes 4.7 seconds to say is printed for 4.7 seconds plus a moment to finish
reading. A line missing from this table has no cached voice clip, and the
caption falls back to the line's own declared `hold`.
WRITTEN BY `game/audio/voicebake.luau`. Edit that — it generates each line once
through the audio service, caches it as a `.soundClip` under
`game/audio/voice/`, and writes its measured length here. Editing this file by
hand makes it disagree with the clips beside it.
Consumed by `game.audio.SoundDirector`.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# game
The shared memory of one BLOCKBUSTER 767 session, and the bus every slice
talks over.
`Game.session` holds what the run is: the state it is in, the score, which
plane is loose, how many are left, the chain and its multiplier, the counts of
blocks shoved and blocks off the table, and the star rating once the session
ends. `Game.telemetry` holds what the airframe is doing this frame — speed,
altitude, pitch, bank, boost and its remaining fuel, the winds the key is
holding, which parts are still attached — written only by the flight slice and
read by the HUD, the camera and the sound mix.
`Game.on` / `Game.emit` are the bus. Handlers run in subscription order, which
matters: more than one slice answers `roundStart`, and which of them the player
ends up looking at cannot be left to the order a table happens to iterate in.
`Game.set` moves the state machine through the names in `game.rules`, and
`Game.reset` / `startRound` / `endRound` / `advance` are the session flow — a
fresh city, a plane on the launcher, a wreck, and then either the next plane or
the end card.
Everything it remembers lives in `modules.state()`, so editing this file while
the game is running does not drop the subscriptions the other slices hold.
Consumed by every slice: `flight`, `city`, `camera`, `ui`, `set` and `audio`.
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).