Timers & watchers#
Some of the best moments in an adventure game happen on a delay: the player rings a doorbell, wanders off, and ten seconds later someone upstairs mutters "the doorbell!" and comes down to answer — wherever the player happens to be by then. Ignitor builds this out of two small pieces, timers and watchers, and this guide shows you how to wire them into a loop that works every time, not just the first time.
The three pieces, in plain words#
- A timer is a kitchen timer. You wind it up with a name and a number of seconds
(
STARTTIMER:doorbell_timer|10), walk away, and it goes off on its own. Nothing happens when it goes off — it just sits there, rung, until something checks on it. - A watcher is a tripwire. It watches a condition every frame ("has
doorbell_timergone off?") and the moment the condition is true it fires its effects — once. After firing, it's disarmed: it will never fire again until something re-arms it. - A behaviour is a routine a character runs on their own — walk here, open that, wander this hallway — no player input involved.
Chain the three and you get the doorbell scene: the click starts the timer, the timer trips the watcher, the watcher launches the reaction.
The loop, drawn out#
This is the actual setup from our Maniac Mansion tribute demo — Weird Ed, upstairs in his room, reacting to the front-door bell:
The example, piece by piece#
Three editors, one piece each:
1. The doorbell hotspot (Room Editor) — the use reaction plays a chime and winds
up the timer. That's all the hotspot knows; it has no idea Ed exists.
SOUND:assets/audio/sfx/doorbell_chime.ogg
STARTTIMER:doorbell_timer|10
2. The watcher (Puzzle Editor, 🌐 Global Watchers tab) — global, because the player has probably wandered into another room by the time the timer goes off, and a global watcher listens everywhere:
id: weird_ed_reacts_to_doorbell
when: timerExpired · doorbell_timer
do: CLEARTIMER:doorbell_timer
CUTSCENE:weird_ed_hears_doorbell
3. The cutscene (Cutscene Editor, 🌐 Global bucket) — Ed reacts, walks to his door, and hands control back. Then his behaviour takes over: a routine that marches him downstairs, room by room, to answer the front door. The final step is the one that makes the whole thing repeatable:
SWITCHCHAR:weird_ed
SAY:weird_ed|"Ah! The doorbell!"
WAIT:1
SAY:weird_ed|"Maybe that's my package!"
WALKNPCTO:weird_ed|1348|358
SWITCHCHAR:{_prevChar}
BEHAVIOUR:weird_ed|weird_ed_notices_doorbell
CLEARWATCHER:weird_ed_reacts_to_doorbell
Ring the bell again after Ed settles back in, and the same ten-second fuse burns down to the same reaction. Every lap of the loop resets itself.
The two golden rules#
Both of these bit us while building the demo, so they're earned wisdom:
An expired timer stays "expired" until you clear it. When it goes off, the timer doesn't vanish — it sits in its rung state, and a
timerExpiredcondition keeps answering yes forever. MakeCLEARTIMERthe first effect of whatever watcher listens for it, or that watcher's condition is permanently true.
A watcher can't re-arm itself from its own effects. The engine marks a watcher as fired after running its effect list, so a
CLEARWATCHERtargeting itself inside its owndoun-marks something that isn't marked yet — a no-op, and the watcher stays dead. Put theCLEARWATCHERat the end of the cutscene (or effect chain) the watcher launched instead. Nice side effect: while the reaction is still playing, the watcher stays disarmed, so mashing the doorbell can't stack five Eds.
A timer as a cooldown gate#
A timer isn't only a fuse for a watcher — you can also ask whether it's still running and use that as a gate. Two conditions read the same timer from opposite ends:
timerExpired— true only after the timer has rung (and stays true until youCLEARTIMERit, per the first golden rule above).timerRunning— true while the timer is still counting down, and false the instant it runs out — or before it ever starts.
That turns a cooldown into a one-liner. Start a timer as the "cooling" window, then guard the
action on timerRunning:
- While
timerRunning→ do nothing (or say "not yet"). The window is still open. - Otherwise → do the thing, and start the timer again. That re-opens the window and blocks a repeat until it burns down.
No companion flag, no re-arming watcher — the timer itself is the memory of "done recently".
Reach for timerExpired when you want a delayed one-shot (the doorbell); reach for timerRunning
when you want to suppress something during a window — a button that can't be spammed, an NPC
that won't repeat a line for a while.
When something doesn't fire#
- "My watcher only works once." It fired and disarmed itself — that's the design.
Add a
CLEARWATCHER:<id>at the end of the reaction it triggers (see rule two). - "My reaction repeats every frame." The watcher is being re-armed while its
condition is still true — almost always a
timerExpiredwith noCLEARTIMER. Clear the timer in the watcher's own effects (see rule one). - "The second ring does nothing." The timer is starting again (
STARTTIMERalways rewinds it) — it's the watcher that's still disarmed. Check that theCLEARWATCHERstep actually runs: it must sit on a path the reaction always reaches, like the last step of the cutscene. - "The timer never goes off at all." Check that its
STARTTIMERactually carries a duration. Seconds starts blank and nothing forces you to fill it in, so it's easy to wire a timer with a name and no number. ASTARTTIMERwith no duration is ignored — no timer starts, sotimerExpirednever becomes true and nothing downstream ever runs.
Where to go next#
- Puzzle Editor — where watchers and global watchers are authored, with the full condition catalog.
- Cutscene Editor — authoring the step lists that reactions like this one launch.
- Effect tokens — the reference table for
STARTTIMER,CLEARTIMER,CLEARWATCHER,BEHAVIOUR, and everything else the effects widget offers.