Kagari
Type to search documentation.

Appendices

Quick Reference

A one-page summary of the language. Each section links to the chapter with the full rules.

Function kinds

KindCallsHolds at runtimeStepsStory variables
fnfn, const fn; starts entry scenes with nav::startanythingnono
#[scene] pushdown fn (scene)scenes, instant procedures, const fn (constant or finite arguments)finite typesyesread and write
pushdown fn (instant procedure)instant procedures, const fn; no recursion, only bounded for loopsfinite typesnoread and write
const fnconst fnanythingnono

Only a scene may run a step, call a scene or call rng_choose. pushdown is a keyword only directly before fn or Fn; scene only in the pointer type scene fn(…) -> …. See Function Kinds.

Pointer typePoints toClosure type
fn(A) -> Ba fnFn(A) -> B
const fn(A) -> Ba const fn or a non-capturing closureconst Fn(A) -> B
pushdown fn(A) -> Ban instant procedurepushdown Fn(A) -> B
scene fn(A) -> Ba scenenone

Attributes

AttributeOnMeaning
#[scene]pushdown fnA scene: may run steps, call scenes and draw random values
#[entry]a #[scene] with finite parameter and return types that contain no TextThe system can start the story here
#[must_use]struct, enumDropping a value, or never completing it, is warning W3023
#[shader_arg]struct with named fields of shader-readable typesThe struct can be a shader’s arguments
#[builtin]functions, structs, traitsImplemented by the compiler and the engine; standard library only

No attribute takes arguments. See Attributes.

Special types

TypeFiniteEqNote
bool, (), Int<lo, hi>yesyesInt<lo, hi> is the story’s integer type
Rust integers, Rat, Decimalnoyes0.5 is a Decimal
Textyesyestype of string literals and t![…]
asset typesyesyesvalues are the asset constants
Option<T>, structs, enums, tuples, arraysif every part isif every part isno recursive types in the story
scene fn, pushdown fn, const fn pointers, Renderyesyes (identity)
fn pointersnoyes (identity)
closuresnonosecond-class in the story
String, Vec<T>, Duration, Color, EntityIdnoyes (Vec if T: Eq)constants are still allowed in the story
Screennoyesthe type renders transform
Setting<T>, Meta<T>, Narrative, Element, screen partsnonoopaque handles and values

See Builtin Types and Language Traits.

Forms (.kix only)

DelimiterAccepts
name!( … )attributes, then a fixed number of elements
name![ … ]elements only, any number
name!{ … }attributes, then any number of elements

Attributes are key = expr, come before the elements, and appear at most once. Elements are separated by commas, except the juxtaposed items of t![…].

FormDesugars toValueAttributesElements
s!(…)push_step(Say { … })()who, voice, render, historyat most one t![…]
choice!{…}push_step(Choice { … })the arms’ value typeid (required, a string literal), renderarms t![…] => V and t![…] if cond => V
t![…]concat([…]) of ruby, mono_ruby, effect and to_text callsTextnone"…", ["基"]("よみ"), ["漢字"]("かん"|"じ"), !["…"](effect), {expr}
column![…], row![…], layer![…]ui::column, ui::row, ui::layerElementnoneany number
text!(…)ui::textElementstyleexactly one
image!(…)ui::imageElementfitexactly one
game_screen!(…)ui::game_screenElementgame (required)none
button!{…}ui::buttonElementon_click, disabled, styleany number
slider!{…}ui::sliderElementvalue (required), on_change, step, disabled, stylenone
toggle!{…}ui::toggleElementvalue (required), on_change, disabled, styleany number
select!{…}ui::selectElementvalue (required), on_change, disabled, styleany number

s! and choice! are allowed only in a scene. The UI forms call fn functions, so they are used in fn code. See Forms and Steps.

Story items

ItemForm
Scene#[scene] pushdown fn Name(…) -> R { … }
Entry scene#[scene] #[entry] pub pushdown fn Main(…) -> Ending { … }
Instant procedurepushdown fn name(…) -> R { … }
Story variablestatic mut NAME: FiniteType = constant;
Settingstatic NAME: Setting<T> = setting(init);
Meta fieldstatic NAME: Meta<T> = meta(init);
Assetconst NAME: ImageAsset = asset("path");, likewise AudioAsset, VoiceAsset, VideoAsset, FontAsset
Shaderconst NAME: ColorShader<Args> = asset("name.wgsl");, likewise MixShader, TextureShader, MaskShader, LocalMotionShader, TransitionalMotionShader; Args is () or a #[shader_arg] struct
System fontconst NAME: FontAsset = system_font("path");
Entity idconst NAME: EntityId = EntityId(n);, with n ≥ 1 (0 is BACKGROUND)
Renderconst fn name(mut screen: Screen) -> Screen { …; screen }
Programfn main() -> System { … } in the root module

Control flow in the story

NeedWrite
Show a lines!(who = "Mio", t!["…"]);
Ask a questionmatch choice!{id = "ask", t!["Yes"] => Answer::Yes, t!["No"] => Answer::No} { … }
Hide an armt!["…"] if condition => V
Call a sceneName(x); or let v = Name(x);
Leave a scenereturn; / return value;, or the block’s final expression
Branchif, if let, match (exhaustive, with ranges and tuples)
Hub or repeated choiceloop { match choice!{…} { … } } with break
Bounded repetitionfor i in 0..n with constant bounds
Change a counterx += 1; (saturates at the bounds of the Int)
Compute from story statecall a const fn; finite runtime arguments are tabulated
Write metaMETA_FIELD.write(v);
Draw at random (scenes only)rng_choose::<T>(), T a fieldless enum or Int<lo, hi>
End the storyreturn from the entry scene; the value goes to the on_exit of nav::start

Common std calls

NeedCallKind
A timems(500), secs(2)const fn
A colourrgb(200, 0, 0), hex(0xC80000), BLACK, WHITE, TRANSPARENTconst fn
A positionpoint(640, 360), offset(0, -20)const fn
Change the backgroundscreen.background().change(BG_ROOF).apply_animation(fade(ms(500)));const fn
Swap a spritescreen.entity(MIO).image().change(MIO_SMILE).apply_animation(cut());const fn
Fade an entity inscreen.entity(MIO).opacity().change(1.0).apply_animation(tween(ms(300)));const fn
Play a motionscreen.entity(MIO).apply_animation(jump(20, ms(300)));const fn
Show a charactercharacter(MIO).show(&mut screen, MIO_SMILE, point(320, 0), tween(ms(300)));const fn
Change the musicscreen.music().change(looped(THEME)).apply_animation(crossfade(secs(1)));const fn
Play a soundscreen.play(sound(CHIME));const fn
Wait in a renderscreen.wait(ms(500));const fn
Style textt![!["red"](color_text(rgb(200, 0, 0))) ![""](click_wait())]in t![…]
Convert integersx.into(), x.saturate()const fn
Read or change a settingMUSIC.get(), MUSIC.set(v)fn
Read metaCLEARED.get()fn
Start the storynav::start(story::Main, (CLEARED.get(),), on_ending)fn
Change modesnav::call(Config), nav::dialog(Confirm), nav::back(), nav::goto(Title), nav::load(slot), nav::quit()fn
A reactive valuelet (count, set_count) = signal(0u32);fn

The names above are in the prelude except the studio’s own constants (BG_ROOF, MIO, …). The full API is in the STD Reference.

Last updated Oct 29, 2026