The whole story on one canvas

A custom canvas editor with content-type color coding, inline title editing, and level-of-detail rendering. Zoom in to work on a single node; zoom out to see the whole narrative flow at a glance. Scales to thousands of nodes without slowing down.

Two drag gestures cover most wiring. Drag from the bottom of a node to send the story onward; drag from the top to make a choice appear only after another node has played. Hold Shift to invert either gesture. Every line you draw is real data, mirrored in the inspector.

Scenes that scale

Break your story into reusable, callable units. Each scene has intro, update, and outro hooks, plus on-leave and on-exhausted for the edges you actually hit: the player walking away, or a scene running out of choices. Scope variables locally where it makes sense; share globally where it doesn't. Nest scenes for sub-sections of a chapter, or call one scene from another and return when it finishes.

Play history is scoped per visit. Re-enter a scene and Played() starts fresh, so intros and one-shot beats re-arm naturally, while PlayedEver() remembers the whole run. Scenes share the canvas, with soft bounding boxes marking each scene's territory.

Choice groups

Group related choices into a single topic that expands when selected: a rumor menu, an interrogation hub, a dialogue wheel. Each group carries a presentation mode your game's UI reads, and the simulator shows groups as labeled columns, so you can feel the shape of a conversation before a single line is recorded.

Conditions that read like sentences

Syntax highlighting colors variables, functions, and operators differently; autocomplete suggests the right thing as you type. Nearly fifty functions cover play history, inventory, time, math, and strings, plus stateful slots like Once, Cycle, and Pick for lines that vary on repeat visits. A "?" help panel opens a quick reference next to every field, and every function has a page in the function reference.

Dynamic text with {var_name} placeholders resolves at runtime, so you cover situational variation without near-duplicate nodes. Rename anything and every expression that references it updates project-wide.

Want to write your next story in StoryBonsai?

Request Access →

A world to write in

The world layer treats spatial state, time, inventory, and skills as core authoring entities. Locations connect into a walkable map with per-connection conditions, ambient audio, and events that fire on arrival and departure. Items are entities; inventory is a list variable you can read, add to, and remove from in any expression.

Time runs on a structured clock with named buckets you define (morning, market hours, curfew) and functions that gate content on it, from IsTimeAfter to Cooldown. A dedicated World Graph draws the whole map from your real data: locations, travel connections, and every scene staged in the world. Details in the world layer manual.

Encounters: stage scenes in the world

An encounter is a scene staged at a location: talk to the bartender, examine the poster, knock on the door. Pick a trigger (a character, an item, or the place itself), set where it's available, and the runtime surfaces it whenever the player is there and your conditions hold.

Give the scene a resolve condition and it retires itself when its business is done. Modal encounters hold the player until they finish; everything else offers a way to leave, with its own lifecycle hook. Staging is one drag on the World Graph or one row in an inspector.

Skill checks with real dice

Drop a Disco Elysium-style check on any node. Pick the skill, write the difficulty as an expression, and add modifiers: each one a label, a value, and an optional condition ("Wearing a suit: +2"). The runtime rolls project-configurable dice (2d6, 1d20, your call) and fires one of four outcome branches; critical success and critical failure can override the ordinary results.

Checks can be one-shot, retryable with an attempt cap, or passive, resolving silently in the background. Every roll shows its full breakdown in the simulator's debug view: skill, modifiers, dice, and the margin.

Activities: the story waits for the player

An activity pauses the story for a structured interaction: allocate the party, brew the tea, spend the points. Bind project variables into groups with selection bounds (exactly one role, up to two skills) and the runtime enforces them; nothing after the activity runs until the player commits, and everything that follows sees their answers.

Your game presents the interaction however fits: a minigame, a QTE, a quiz. The runtime supplies the fields and the rules, your UI returns the values, and the simulator plays every activity with a built-in reference UI before any game UI exists. Details in the activities manual.

How do you localize a branching story?

Write in your source language; translations layer on top without touching your project. The editor tracks what's translated, flags entries that went stale when you edited the source, and exports translator handoffs in CSV, JSON, or XLIFF. ICU message format handles plurals and gendered text per locale.

Flip the locale switcher and the whole editor follows, with untranslated lines outlined red in the simulator. Structural edits stay locked to the source locale, so a translation pass can't break the story. The full workflow is in the localization manual.

Built-in simulator

Messaging-app playback, including video and captions, with placeholder text for unrecorded lines. Four advance modes range from click-through to a cinematic mode that paces every message. A breadcrumb of your choices lets you rewind to any past decision without restarting, and each crumb carries a full state snapshot.

When no scene is active, you walk the world itself: start encounters, travel between locations, watch time advance. Debug mode interleaves variable changes, jumps, and skill-check breakdowns with the dialogue; each kind has its own filter.

Test the story, not just the syntax

Expression tests pin condition behavior. Define cases (these variables, this play history, this inventory, this time of day) and lock in the expected outcome. Stops "fixed once, broken later" regressions before they ship. The editor suggests scenarios by reading the variables an expression uses and proposing boundary cases; keep the ones that match your intent. A playground evaluates any expression against any state, one click from saving it as a test.

Tests live with the field they describe, so renaming a field doesn't break its tests.

Reverse references

Select any node, variable, character, scene, location, item, skill, or tag. Instantly see every node that references it, with the exact field (visible when, event condition, event target) and one-click navigation. Find every place a variable is read or written before refactoring it.

How does automated path testing work?

Play thousands of versions of your story to catch broken paths before players find them. The path tester surfaces what a static scan cannot: variable min/max violations, unreachable nodes with explanations, duration mismatches, infinite loops. Four strategies (random, defaults-first, coverage-guided, and goal-seeking) each explore the story differently, and the tester walks the world alongside choices: moving between locations, starting encounters, advancing time. A coverage heatmap overlays the graph to show where the story is under-tested.

Every run reports back inside the editor with statistics, issues, and per-scene breakdowns; click any flagged node to jump straight to it. No terminal, no context switch.

Project correctness at a glance

Real-time validation shows errors on node cards, the minimap, the project tree, and inside the inspector. The Project Validator panel lists every error across the project in one place with click-to-navigate: dead-code flags, meter and bounds warnings, tag validation, and expression return-type mismatches. Catch problems at edit time, not at playtest.

Story beats

Mark the narrative moments that matter inside your videos and audio: "player saw the betrayal," "player met Claire." The engine remembers which beats the player has actually seen and at what importance. Your developers can build recaps, callbacks, and "previously on…" moments from story content you already wrote, with no separate tracking system.

Canvas filters

Combine text, tag, scene, and player filters with boolean operators. Right-click any node to filter by its tags or player. Find anything in a project of any size, instantly.

Single-player or multiplayer. Built into the runtime.

Author conversations across multiple players. Choices belong to players; the editor keeps it all straight.

Coming soon

In active development.

Style-guide linting. Rules like "max 25 words per choice" enforced at edit time.

Request Access →

Screenshot viewer