Control
Control is a class that has some utility methods for flow control.
Control.do([
character1.say("hello"),
// play sound and shake image at the same time
Control.allAsync([
sound.play(),
shake(image1),
]),
]);Static Method
do
Execute actions in order, waiting for each action to complete
actions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
doAsync
Execute actions in order, do not wait for this action to complete
actions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
any
Execute all actions at the same time, waiting for any one action to complete
actions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
all
Execute all actions at the same time, waiting for all actions to complete
actions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
allAsync
Execute all actions at the same time, do not wait for all actions to complete
actions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
repeat
Execute actions multiple times
times: number- timesactions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
whileLoop
Execute actions while condition is true
const loopState = new Persistent("loop-state", {
tries: 0,
});
story.registerPersistent(loopState);
scene.action([
loopState.set("tries", 0),
Control.whileLoop(loopState.evaluate("tries", (tries) => tries < 3), [
character.say`Attempt ${loopState.get("tries")}`,
loopState.set("tries", (tries) => tries + 1),
]),
]);condition: Lambda<boolean> | LambdaHandler<boolean>- condition to checkactions: ActionStatements- ActionStatements- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
breakLoop
Break the current loop (repeat/while) Can only be used inside a loop body
scene.action([
Control.whileLoop(loopState.evaluate("tries", (tries) => tries < 10), [
Condition.If(loopState.equals("tries", 3), [
character.say("Stop here."),
Control.breakLoop(),
]),
loopState.set("tries", (tries) => tries + 1),
]),
]);- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
sleep
Sleep for a duration
duration: number | Awaitable<any> | Promise<any>- sleep duration- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
waitForClick
Pause execution until the user clicks anywhere on the stage (excluding GUI elements such as dialog, buttons, menus). Similar to inserting a pause with no duration in a Sentence.
Useful for creating "click to continue" moments in ADV mode, or for pausing within NVL blocks until the player is ready to proceed.
scene.action([
character.say("Read this carefully..."),
Control.waitForClick(),
character.say("Now we continue."),
]);- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
label
Mark a named point inside the current scene that jump can jump to. A label is invisible at runtime — it simply passes through to the next action.
Label names are scoped to the scene they are declared in, so the same name may be reused across different scenes. Declaring the same name twice in one scene fails the build.
scene.action([
Control.label("intro"),
character.say("Let's begin."),
]);name: string- the label name, unique within its scene- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance
jump
Jump to a label elsewhere in the same scene and resume playing from there.
Unlike Scene.jumpTo, this stays inside the current scene — no scene is unloaded or re-initialized, only the play head moves. The target must be a label declared in the same scene, otherwise the story fails to build.
Control.jump redirects the main story flow, so place it as the last action of a branch (such as a menu choice). To loop a scene, drive the loop through a menu or condition rather than jumping out of a repeat / while body.
scene.action([
Control.label("start"),
Menu.prompt("Again?")
.choose("Yes", [Control.jump("start")])
.choose("No", []),
]);name: string- the name of the target label, declared in the same scene- Returns
Proxied<Control, Chained<LogicAction.Actions>>- Chained Control instance