Conductor
The rules of THE EIGHTH KETYL. One component, on the `Game` entity, and the only writer of `Still.state`.
Conductor
The rules of THE EIGHTH KETYL. One component, on the Game entity, and the only
writer of Still.state.
The state machine
title ── "start" ──▶ intro ──(9s, or any control)──▶ play
│
the plate's growths are gone ──▶ cleared
│ │
wetness hit maximum ──▶ quenched ascend │
│ │
plate 8 went clean ──▶ sealed │
◀──────┘
cleared is a playable phase. The plate is done and the riser is lit, but
the ketyl still has to drift to it and commit, so movement, discharge and surge
all answer during cleared exactly as they do during play. Still.state.phase
distinguishes them so a screen can say "the way up is open" without the game
having stopped.
paused remembers what it interrupted and returns to it.
What it emits
phase · runStart · plateEnter · plateCleared · riserOpen · ascend ·
sealed · quenched · charge · wetness · discharged · surged.
charge and wetness are announced on a real change rather than every frame; a
bar that draws every frame should read Still.state directly instead.
What it listens for
| Event | From | What it does with it |
|---|---|---|
uiIntent(name) | presentation | start · resume · restart · quitToTitle |
growthCount(alive, total) | blennoma | writes the count; alive == 0 lights the riser |
soaked(amount) | blennoma | amount is wetness points — a pool sends its per-second rate times dt, a droplet sends its whole lump |
sodiumTaken(pos) | blennoma | credits Still.SODIUM_RESTORE charge |
It does not know what a blennoma is, where a droplet fell, or what any screen
says. A discharge goes out as discharged(pos, dir) and the blennoma slice
decides what stood in the arc.
When nobody reports a plate
plateEnter(n) asks the blennoma slice to build plate n's field. If no
growthCount arrives within KetylCore.GROWTH_GRACE seconds the plate is
treated as empty and the riser opens, so the column stays climbable while that
slice is mid-build — and it says so at WARN, because a riser that opens for no
reason is otherwise indistinguishable from a plate that was genuinely cleared.
Callable
The same decisions the controls reach, by name, for a test or anything that has to drive the game without a pair of hands:
local cond = Still.anchor("Conductor").component.get("Conductor")
cond:startRun(false) -- begin a run, skipping the opening
cond:toTitle()
cond:discharge()
cond:surge()
cond:ascend()
cond:togglePause()
Scoped to this part · feeds back into the world's score.