Game
The loop of *First Light: Luteway*. It sits on `mount_game` and is the only writer of `LW.state.phase`, `LW.state.run`, `LW.state.tide` and `LW.state.dawn.t`.
Game
The loop of First Light: Luteway. It sits on mount_game and is the only
writer of LW.state.phase, LW.state.run, LW.state.tide and
LW.state.dawn.t.
title ──start──▶ opening ──(staging releases)──▶ play ──▶ won | lost
│ pause ▲ resume
▼ │
paused ───┘
A screen moves the loop with LW.emit("uiRequest", action) — start, pause,
resume, restart, title — and this answers. The opening is held while the
staging slice has LW.state.stagingBusy set, and released on its own after nine
seconds so a missing or mid-edit crane can never leave the player without
control.
The two clocks
The sea is defined by WHEN it takes the rookery rather than by how fast it
rises, so a route of any height gets the same deadline and the same shape of
pressure: slow at first, gathering, over the crest at RUN.drownSeconds.
Standing on the beach doing nothing drowns in about fifteen seconds; a run that
keeps moving has room, and one that dawdles does not.
The light runs on the clock too, but it can never fall behind the penguin:
dawn.t is the greater of the clock's share and the climb's, and only ever
increases. A fast climber arrives into a dawn that kept up with them; a slow one
gets it anyway. The cliff slice turns that number into the sky, the sun and the
light line coming down the rock.
Ends
Lose when the sea reaches the penguin's chest. Win when it is standing on the
rookery ledge — dawn.t goes to 1 and firstLight fires with it.
Staying wired
Reloading luteway.game gives it a new event bus while this component keeps
running, and every subscription made against the old one is gone: the loop would
answer no button on any screen, and nothing would report an error. So it emits a
probe on the bus once a second and subscribes again when its own handler does not
answer.
Scoped to this part · feeds back into the world's score.