Beats
The moments THE EIGHTH KETYL is remembered by, as camera data.
staging.Beats
The moments THE EIGHTH KETYL is remembered by, as camera data.
Each function returns a cutscene definition built against the live screen and
the live state of the run — the column's geometry out of Still, the framing
solver out of staging.Frame, and the ketyl wherever it is standing. There is
no literal camera position anywhere in this module.
local Beats = require("staging.Beats")
cutscene.play(Beats.opening(ketylBody, playSound))
cutscene.play(Beats.plateClear(3))
The moments
opening(body, onSound) — three shots. The shaft from below with the plates
stacking up a tall frame; a drift across the plate you are about to play; a
settle that ENDS on the pose the playing camera holds, so the handover is a
continuation rather than a cut. Cut to introSeconds() — the core slice's own
intro clock — because that slice hands the player their hands back on it whether
or not a camera has finished. Cues v_open_1..3.
plateClear(n, onSound) — 2.7 s. The frame leaves the ketyl, pushes onto
the riser as it lights, holds long enough to be read, and gives the plate back.
Short on purpose: it happens seven times. Cues v_clear.
ascend(from, to, body, onSound) — 2.6 s in two shots: up through the mouth
of the riser from the plate being left, then a rise onto the plate above as the
ketyl arrives on it. Cues that plate's v_plate_n.
sealed(body, onSound) — 11.6 s, and the only time the whole column is seen
at once: in on the radical, a long crane down every plate it burned clean, then
a held look back up the sealed still, fading to a dark violet. Cues v_seal_1
and v_seal_2.
quenched(body, plate, onSound) — 6.6 s. Close while there is still
something to see, then away and down until the still is standing there without
it. Fades to black. Cues v_quench.
Stations
Beats.station(px, pz, dist, delta, y) places an eye dist from a point on a
plate, delta radians off directly-across-the-column, at height y. It solves
the radius through Frame.eyeRadius, so a cinematic camera is never outside the
sealed still looking at the outside of black glass.
Frame.ring(angle, y, radiusFrac) is the same idea for a shot that orbits the
axis rather than a subject.
Anchors are ids, not proxies
Every shot that follows the ketyl names it by id string. A cutscene anchor reads a value as a position before it reads it as an entity, and an entity proxy raises when it is indexed that way — so a proxy anchor refuses the whole cutscene. An id is the same subject, tracked the same way, through a path that works.
Scoped to this part · feeds back into the world's score.