Docs Examples
Examples
Copy-paste patterns for the most common structures. Swap in the character names, asset filenames and variable names you’ve registered in your project.
A full chapter
Backgrounds, dialogue, choices, variables, conditionals, jumps and endings working together.
chapter_one.omi
OmiScript
## 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
Branching choices
branching.omi
OmiScript
// Choices can be conditional — an option only appears when its [$condition] is true. // Conditions read session variables ($var) declared in Studio → Variables. ? "What do you say?" - "I believe you" [$trust >= 1] // This option only shows if $trust is at least 1 player: "I believe you." sarah: "Thank you. Really." $route = "friendship" -> Good Path - "I don't trust you" // No condition — always visible player: "I don't trust you." sarah: "That's fair. But you're wrong." $route = "tense" -> Tense Path - "Stay quiet" [$met_sarah == false] // Only available if the player hasn't met sarah yet "You said nothing. Safer that way." -> Quiet Path
Messenger scene
messenger.omi
OmiScript
// Switch to a messenger-type app registered in Studio → Apps. // All @chat content is deposited into that chat's message log. @app chatter // Open a specific chat — chatId must be registered under this app in Studio. @chat chat_sarah // Messages drip in one at a time as the engine runs sarah: "hey, you there?" sarah: "hello??" // Reply gate — the player picks one option to send as their message ? reply: - "sorry, was asleep" player: "sorry just woke up lol" sarah: "okay good, we need to talk" // Track that the player replied — useful for branching later $replied_sarah = true -> Replied - "leave on read" // No player message — sarah gets no response -> Left On Read ## Replied sarah: "meet me at the usual spot. 20 mins." @end ## Left On Read // Push a notification into the player's notification shade @notify chatter "Sarah" "is waiting for your reply..." @end
Conditional branching
conditional.omi
OmiScript
// ? if / ? elif / ? else — conditional blocks. // Evaluates against session ($var) or persistent ($$var) variables. // Only the first matching branch executes. ? if $route == "friendship": sarah: "I'm glad we talked." player: "Me too." ? elif $route == "tense": sarah: "I hope you change your mind." player: "Maybe." ? else: // Fallback — runs when no other branch matched "They stood in silence." // Comparison operators: == != > < >= <= // Logical: and or not // Example multi-condition: ? if $score >= 10 and $met_sarah:
Phone call (SimOS)
phone.omi
OmiScript
## The Call // Switch to a phone-type app registered in Studio → Apps @app phone // Incoming call gate — the player picks Answer, Decline, or another branch. // Dialogue inside a branch becomes the in-call conversation in the Phone app. ? call from sarah: - "answer" sarah: "Hey. Are you alone?" player: "Yeah, why?" sarah: "I need you to listen carefully." sarah: "Don't come to the office tomorrow." -> After Call - "decline" // No in-call dialogue — goes straight to the branch body -> Missed Call // 'hang up' is a special branch — runs when the player taps End Call mid-conversation - "hang up" sarah: "...hello?" -> Hung Up ## After Call "She hung up before you could ask anything." @end ## Missed Call // Voicemail — deposited into the phone app's voicemail inbox @voicemail vm_sarah_001 from: sarah duration: 0:12 transcript: "It's me. Call me back. Please." @end ## Hung Up "You stared at the phone. Had that been a mistake?" @end
Social feed (SimOS)
social.omi
OmiScript
## The Post // Switch to a social_feed-type app registered in Studio → Apps @app social_feed // Posts deposit into the feed as the engine runs — displayed newest-first in the UI. // 'image' is a logical name from Studio → Assets → CGs (no file extension). @post post_morning by: sarah text: "Another late night at the office. Someone send help ☕" image: sarah_office likes: 12 likeable: true // Comment gate — the player picks a reply to a specific post. // appId and postId must reference what's already been deposited above. ? comment on social_feed post_morning: - "Hang in there!" player: "Hang in there, you've got this!" sarah: "Aw, thanks 🥺" -> After Comment - "Say nothing" -> After Comment ## After Comment // Push a banner notification into the player's notification shade @notify social_feed "Sarah" "liked your comment" "Your notification lit up a moment later." @end
Premium feed with subscription (SimOS)
premium.omi
OmiScript
## The Exclusive // Premium feed — requires a premium_feed-type app in Studio → Apps @app vip_feed // free: true — always visible regardless of subscription status @post post_free_001 by: creator text: "Hey everyone, big news coming soon 👀" likes: 204 likeable: true free: true // locked_until — the post is blurred with a lock overlay until the condition is true. // player_subscribed_to(appId, userId) is a built-in engine expression. @post post_locked_001 by: creator text: "Here's the full behind-the-scenes video from last night." image: bts_video_thumb locked_until: player_subscribed_to(vip_feed, creator) teaser: "Subscribe to unlock exclusive content 🔒" // ? subscribe to — narrative-driven subscription gate. ? subscribe to vip_feed creator: - "Subscribe" creator: "Thank you so much! 🥺" // Persistent — survives across playthroughs, so future chapters know $$subscribed_vip = true -> Subscribed - "Maybe later" -> Skipped ## Subscribed "The locked post shimmered and revealed itself." @end ## Skipped "The blurred post remained. For now." @end
Character sprites
sprites.omi
OmiScript
## The Confrontation // 'rooftop_night' is a logical name from Studio → Assets → Backgrounds @bg rooftop_night // Auto-stage: speaking with () triggers automatic sprite placement. // The first speaker goes center; the second speaker pushes the first aside. sarah (): "You followed me up here." player (): "You left me no choice." // Named expression — registered in the character's sprite map in Studio. // Use () for the default expression, (name) for a registered variant. sarah (angry): "Don't make this harder than it has to be." // Explicit placement — overrides auto-staging, puts marcus in the left slot. @sprite left marcus marcus: "Nobody's going anywhere." // Clear a slot — removes the sprite visually when a character exits. @sprite left clear // sarah and player remain staged in their auto-assigned slots. sarah: "It's just us now." // @end — chapter complete. Use @fin to end the entire story. @end
Storyomi Creator Docs
Back to Storyomi