Skip to content

KAG Script Basics

import { Tabs, TabItem, Aside, Badge } from '@astrojs/starlight/components';

KAG scenarios are plain text files (.ks) that can embed Rhai expressions for conditional logic, variable mutation, and dynamic text.


A .ks file is processed line-by-line. Each line is one of:

Line typeExampleMeaning
TextHello, world!Printed to the message window
Label*startJump target
Speaker shorthand#AliceSets the speaker name for the next text block
Block tag[wait time=500]Inline tag (must be the only content on the line)
Line tag@jump target=*start@ is syntactic sugar for […]
Comment; this is a commentIgnored by the interpreter
*my_label

Labels are * followed by an identifier. Labels are used as jump targets for [jump], [call], [link], etc.

#Alice
This text is attributed to Alice.

The #Name shorthand sets the current speaker name. The name is reset after the next text block is emitted.


KAG exposes four variable maps as Rhai global objects:

NameScopePersistenceUse case
fGame flagsSaved with the gameStory flags, counters, choices made
sfSystem flagsSaved separately from game savesConfig, global unlocks
tfTransient flagsNot saved — reset on loadTemporary per-scene values
mpMacro parametersSet at macro call sitePass-through inside [macro] bodies

Access and mutate them like Rhai object maps:

f.visited_village = true;
sf.bgm_volume = 0.8;
tf.temp_counter = tf.temp_counter + 1;
TagEffect
[clearvar]Clears all f entries
[clearsysvar]Clears all sf entries

Runs a Rhai script without producing any output.

[eval exp="f.score = f.score + 10;"]
[eval exp="f.name = mp.player_name;"]

Side-effects (variable mutations) are persisted into the scope.

Any attribute value prefixed with & is evaluated as a Rhai expression at runtime:

[jump target=&"*" + f.next_scene]
[bg storage=&"bg/" + sf.theme + "/bg01.jpg"]

Macro parameter references (%key / %key|default)

Section titled “Macro parameter references (%key / %key|default)”

Inside a [macro] body, %key is substituted with the value passed at the call site. An optional default follows |:

[macro name=say_hello]
Hello, %name|stranger!
[endmacro]
[say_hello name=Alice]