Log inGet started
World

The Eighth Ketyl

Branchmain
Branchesmain
Commite99ff0a216

README.md

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.