Director
The staging slice of SLAG SAINT: the moments between the blows. Attach it to `stage_root` — `BattleBoot` does that on its own the moment the component exists.
Director
The staging slice of SLAG SAINT: the moments between the blows. Attach it to
stage_root — BattleBoot does that on its own the moment the component
exists.
It owns three things no other slice touches.
The flow. Rules.setMode runs through here and nowhere else:
title → intro → fight, then victory or defeat, and back to fight
on a retry. Anything else that wants the fight to start (or start again)
raises battle:begin rather than setting the mode itself.
The clock. engine.timeScale is the Director's. Raise
hitstop { duration } and it bites for a fraction of a second and lets go;
the longest outstanding request wins, so two hits landing together do not cut
each other short. It also stops for a landed Quench (player:attack
{ kind = "crit" }), a parry and the moment the saint's poise breaks, whether
or not anybody asked for it.
The camera, while the mode is not fight. Every staged moment is played
through the engine's cutscene system, which takes the camera above the
gameplay one and gives it back when the shot is over. CombatCamera yields by
reading Rules.state.mode.
What it plays
| Moment | Raised by | What it does |
|---|---|---|
| Title | entering play | A slow drift under the title card. Any key starts the game. |
| Opening | the title ending | The descent into the basin, the Emberward's two lines, the first bell. |
| Entrance | the opening ending | A crane from the saint's feet to its bell, and its greeting. |
| Phase beat | phase:changed | 1.9 seconds. You notice it; you do not lose the fight. |
| Victory | boss:defeated | The light goes out of it from the feet upward. |
| Defeat | player:died | From the floor, looking up at what is still standing. |
| Pulse | a Quench, a parry, a stagger | A letterbox squeeze over live gameplay — no camera taken, no freeze. |
The shots themselves are data in game/staging/sequences, so a re-timed
moment is an edit to that module and not to this component.
Nothing here is in world coordinates
The saint walks. Every camera station is built in a frame whose forward axis runs from the ward to the saint, wherever the two of them are standing when the moment begins, and the distances are measured against how tall the saint actually is. A shot written against the arena's own coordinates frames empty floor the moment the fight moves.
Handles
local d = entity.find("stage_root").component.get("Director")
d:status() -- stage, mode, phase, timeScale, what is playing
d:replay("entrance") -- watch one moment: title | opening | entrance |
-- phase2 | phase3 | victory | defeat
d:begin() -- skip the staging and start the fight
d:restart() -- put the fight back to its first frame
d:punch(0.2) -- ask for a hitstop without the event bus
autoOpen = false on the component stops it seizing the camera when play
starts, which is what another slice's author wants while working on the fight
itself.
The watchdog
A staged moment that stops advancing would hold the camera and the player's controls for the rest of the session. The Director watches the playback's own clock: if it sits on the same frame for 2.5 real seconds, or outlives its shot list by six, the moment is abandoned, the overlay is swept and the flow carries on to whatever was supposed to come next.
Scoped to this part · feeds back into the world's score.