Docs OmiScript

OmiScript

The language behind every Storyomi story. Every construct is introduced by a single character — learn the sigils and you know the whole language.

The sigils

The complete core vocabulary. Reference pages in this guide walk through each family with examples.

SigilWhat it doesExample
## Scene NameStarts a named scene — used as a jump target## The Rooftop
"text"Narration — no speaker, prose overlay"The rain fell harder."
speaker: "text"Character dialoguesarah: "I'm scared."
speaker (expr): "text"Dialogue with a sprite expressionsarah (worried): "I can't."
? "Label"Choice gate — the player picks a branch? "What will you say?"
- "Option"A choice option (two-space indent) - "Run"
-> NameJump to a named scene-> The Roof
@endEnd of chapter — loads the next published chapter@end
@finEnd of story — the whole game is over@fin
@bg filenameSet a background image@bg city_night
@cg filenameSet a full-screen CG image@cg monster_reveal
@app appIdSwitch to a registered SimOS app@app chatter
@sprite slot charIdStage a character sprite in a slot@sprite left sarah
@sprite slot clearRemove a sprite from a slot@sprite left clear
$var = exprAssign a session variable$score = 0
$$var = exprAssign a persistent variable$$saw_ending_b = true
? if cond:Conditional block? if $score >= 10:
// commentStripped at compile time// fix this later
@app is for Simulated OS games only. Standard VN games run in the VN context automatically — you never need to write @app unless you’re switching between registered SimOS apps.

Scenes

A chapter is made of named scenes. Scene headers give you stable places to jump to.

Start a scene with ## Scene Name. Scenes are the units of structure — each branch lands on a named scene, and a new scene is the natural place to change location or mood.

scenes.omi
## The Rooftop
@bg rooftop_night

sarah: "You followed me up here."

-> The Rooftop
Scene headers do not clear sprites automatically. If a character leaves, clear them explicitly with @sprite left clear.

Narration

Prose with no speaker — the narrator’s voice, or the world describing itself.

A quoted string on its own line is narration:

narration.omi
@bg city_night

"It was 2 AM when the phone buzzed."

"She put the phone down. Big mistake."

Dialogue

A speaker name, a colon, and their line. The speaker must be registered in Studio → Characters.

Plain dialogue keeps the speaker’s current sprite staged. Add parentheses for an expression, or empty parentheses to auto-stage the speaker’s default sprite:

dialogue.omi
player: "Who texts at this hour?"
stranger: "Turn around."
stranger (): "I'm not joking."
stranger (serious): "Look at the window."

Choices

A question to the player. The engine pauses here and waits for a pick.

The gate is ? "prompt" and every option is indented two spaces and starts with -:

choices.omi
? "What do you do?"
  - "Turn around slowly"
    player: "My hands are shaking."
    -> The Reveal
  - "Ignore it"
    "She put the phone down. Big mistake."
    -> Bad End

Options can be hidden behind a condition with [$var >= 1] — see Variables & Conditionals.

Jumps

Send the player to any named scene with an arrow.

-> Scene Name jumps to a scene header anywhere in the chapter. This is how branches merge — both options land on a shared scene.

jumps.omi
## Choices
? "Tea or coffee?"
  - "Tea"
    -> The Kitchen
  - "Coffee"
    -> The Kitchen

## The Kitchen
mira: "Good choice."

Endings

Two ways to stop. Pick the one that matches the story’s shape.

@end — chapter complete

Ends the current chapter. If a newer chapter is published, the player is carried straight into it. If not, they see the end-of-chapter screen.

@fin — story over

Ends the entire story. Use it for true endings and bad ends. Players can’t continue past it.

endings.omi
## Bad End
"Three hours later, she was gone."
@fin

## Good End
"She was still there. Waiting."
@fin

Everything together

A complete chapter combining scenes, narration, dialogue, choices, variables, conditionals, jumps and both kinds of ending:

chapter_one.omi
## The Message
// Register 'stranger' in Studio → Characters, 'city_night' in Assets → Backgrounds,
// and '$met_stranger' (boolean) in Studio → Variables before running this script.

@bg city_night

// Narration — no speaker, shown as prose overlay
"It was 2 AM when the phone buzzed."

// Dialogue — speaker must be registered in Studio → Characters
player: "Who texts at this hour?"
stranger: "Turn around."

// Choice gate — player picks one branch; the engine waits here
? "What do you do?"
  - "Turn around slowly"
    player: "My hands are shaking."
    stranger: "Smart choice."
    // Session variable assignment — saved with save slots
    $met_stranger = true
    -> The Reveal

  - "Ignore it"
    player: "Probably spam."
    "She put the phone down. Big mistake."
    -> Bad End

## The Reveal
@bg alley_night

"The figure stepped into the light."

// Conditional — branches on a session variable value
? if $met_stranger:
  stranger: "I knew you'd come."
? else:
  stranger: "You shouldn't be here."

stranger: "We need to talk. Not here."

// @end — chapter complete, engine loads the next published chapter
@end

## Bad End
@bg city_night

"Three hours later, she was gone."

// @fin ends the entire story, not just the chapter
@fin

Storyomi Creator Docs

Back to Storyomi