Events
Events let your code respond to what’s happening in the novel. Use onChange to respond when a value changes, and onLabel to handle labels in the screenplay.
onChange
Section titled “onChange”Runs a callback whenever a watched value changes.
onChange<T>( getValue: () => T, onUpdate: (currentValue: T) => void): () => void| Parameter | Description |
|---|---|
getValue | Returns the value to watch. Inkweaver calls it whenever state changes, and compares the result to the last one. |
onUpdate | Called with the new value when it changes. |
Returns a function that stops watching.
onUpdate runs once at startup with the starting value, before the story begins. After that, it runs on every change, including when the reader rewinds or loads a bookmark, so it must be idempotent. If your logic can’t be idempotent, move it into a command.
If onUpdate changes state in a way that causes any recursion, Inkweaver throws an error.
Example
const stopWatching = onChange( () => getState().trust, (trust) => console.log(`Trust is now ${trust}`),);onLabel
Section titled “onLabel”Runs a callback when the reader reaches a line with a matching label.
onLabel<T extends BlockLexia>( pattern: string | RegExp, callback: (lexia: T, args: Record<string, string>) => LabelResult<T> | Promise<LabelResult<T>>): void
type LabelResult<T> = void | null | boolean | T;| Parameter | Description |
|---|---|
pattern | A string that matches a label exactly, or a regular expression for labels with parameters. |
callback | Receives the line’s lexia, and args: the named capture groups from pattern. args is empty for a string pattern. |
The callback runs when its line is read, and can be synchronous or asynchronous. Inkweaver waits for it before handling the line.
| Return value | Result |
|---|---|
undefined, nothing, or true | The line is shown as normal. |
null or false | The line is skipped. |
| A lexia of the same type | The line is replaced with the returned lexia. |
To work with a specific kind of line, pass its type as T, and the callback receives that type. Inkweaver can’t check this for you. If the label appears on a different kind of line, your callback receives that kind regardless of T. Use the default, BlockLexia, unless you control where the label is used.
Example
/* * Screenplay usage: * * SOPHIA <if-trustworthy> * I have something important to say... */onLabel("if-trustworthy", () => { const { trust } = getState(); return trust >= 5;});onLabel<DialogLexia>("shout", (lexia) => ({ ...lexia, content: toUpperCase(lexia.content),}));With named capture groups, the screenplay can pass values to your code. Here, the screenplay sets the trust range for each line:
/* * Screenplay usage: * * SOPHIA * I'm not sure I can share this with you... <if-trustworthy 0-3> * I have something important to say... <if-trustworthy 4-10> */onLabel( /if-trustworthy (?<from>[0-9]+)-(?<to>[0-9]+)/, (lexia, { from, to }) => { const { trust } = getState(); return trust >= parseInt(from) && trust <= parseInt(to); },);