Staging
The camera of THE EIGHTH KETYL, and the moments it attends to. It sits on the `Staging` host entity in `still.scene` and is the only thing in the game that moves the camera.
Staging
The camera of THE EIGHTH KETYL, and the moments it attends to. It sits on the
Staging host entity in still.scene and is the only thing in the game that
moves the camera.
What it does
The playing shot. On the first frame it can, it installs staging.KetylCam
on the player's CameraRig as that camera's behavior, in place of the orbital
rig the scene ships with, and points it at whatever Camera.follow names. That
component owns the framing; this one owns getting it there and getting it back
after a cinematic.
The moments. Five cutscenes out of staging.Beats, each triggered by an
event the core slice emits:
| Event | Moment | Runs for |
|---|---|---|
runStart / phase("intro") | the opening — the still, before you may move | the core slice's own INTRO_SECONDS |
plateCleared(n) | the push onto the riser as it lights (plates 1–7) | 2.7 s |
ascend(n, to) | up through the riser onto the plate above | 2.6 s |
sealed() | the win — in on the ketyl, then the whole column | 11.6 s |
quenched() | the loss — close, then away and down | 6.6 s |
Plate 8 gets no clear beat: the seal is arriving a moment later and two cinematics on one beat cut each other off.
The lines. It cues spoken lines by id through staging.Voice and never
writes the words — the sound slice owns those. The opening cues v_open_1..3,
an ascent cues that plate's v_plate_n, a clear cues v_clear, the endings cue
v_quench and v_seal_1 / v_seal_2. Wetness crossing 72% of maximum cues
v_wet and charge falling under 18% cues v_low, each once per crossing.
Its own sound. Three clips under staging/audio play under the beats,
below whatever the sound slice plays on the same moment: stg_frame when a
moment takes the frame, stg_rise on an ascent, stg_reveal on the seal.
Events
Emits shot(name) when a moment takes the camera — "opening", "plateClear",
"ascend", "sealed", "quenched" — and shot("free") when one gives it
back. A screen that should not land on top of a resolution waits for "free"
rather than for the phase, which changes while the shot is still running.
Emits line(id, text, speaker) and lineEnd(id) through staging.Voice.
Listens for runStart, phase, plateEnter, plateCleared, ascend,
sealed, quenched, wetness and charge.
Skipping
Every moment but the opening can be skipped from all three device families: for
the length of a moment this component holds the console input map, whose
confirm, back and resume each carry a key, a pad button and an on-screen
button. Map holders are refcounted, so this takes nothing from the slice that
owns that map for menus.
The opening is the core slice's to end — its pause control leaves the intro
phase, and this component skips the camera when the phase moves to play, so
the two clocks cannot disagree.
Fields
| Field | Default | What it does |
|---|---|---|
cinematics | true | Off, the game plays with no moments at all. The playing camera still works — for filming the loop with nothing in the way. |
beatVolume · riseVolume · revealVolume | 0.55 · 0.62 · 0.50 | The camera's own sounds, under the mix. |
wetWarnAt / wetRearmAt | 0.72 / 0.55 | Where v_wet fires and re-arms. |
lowWarnAt / lowRearmAt | 0.18 / 0.38 | Where v_low fires and re-arms. |
Rehearsing
local staging = require("Still").anchor("Staging").component.get("Staging")
staging:rehearse("sealed") -- watch a moment now
staging:rehearse("plateClear", 5) -- ... on a particular plate
staging:release() -- take it off and give the shot back
staging:report() -- the moment, the rig, the live framing
Scoped to this part · feeds back into the world's score.