📌
⚠️ This is NOT official documentation. A fan-made guide by Frozen_Tuna, written while actually building on the Canvas. It is not written, reviewed, or endorsed by StoryEngine and has no affiliation with the platform.
Parts of the platform's internals are deliberately undisclosed, so some of this is guesswork and some of it is simply wrong. Numbers change without notice. Keep the Canvas open and believe the Canvas over this document, every time.
🔢
Want to count tokens before you paste? This guide is full of token limits — 2,000 for Core Context, 500 for a preset note, and so on — but the Canvas doesn't show you a count while you write. A handy stand-in: Tiktokenizer with the o200k_base encoding. Paste your text and it counts tokens live.

Why o200k_base: StoryEngine creators were told the tokenization follows GPT-4o's scheme — note that's a statement about how tokens are counted, not a claim about which model runs underneath. o200k_base is GPT-4o's tokenizer, so the counts should line up. Treat it as a close estimate, not an exact match — this hasn't been verified side-by-side against the Canvas, and CJK text especially can differ between tokenizers. When it matters, trust the Canvas's own counter. (Tip from アヤイヤオ.)
🗂️

What is the Canvas?

The Canvas is the workspace where you place and connect the nodes (blocks) that make up a story chat. Each node has a defined role, and you wire them together to create the flow of data.

Minimum setup Story + Character + User
Connect these three and the chat works. Everything else is added capability.
Data flow What's in a node reaches the AI
The Canvas is a tool for structuring "what gets handed to the AI." Whatever you write in a node is compiled and enters the AI's context.
🔌
Connecting nodes: click the port, don't drag the wire. Every node has labelled input ports down its side — and this works the same way on all of them, not just the story node. Click or tap a port and a list of every node eligible for that slot pops up; pick one and it wires itself. Image ports behave identically: tap an emotion- or situation-image port and it lists the image nodes you can attach, each with its tag. Hand-dragging wires is miserable on mobile, so this is usually the faster way to build regardless of device.
An image port on a character node clicked open, showing a dropdown list of selectable image nodes each marked with its tag
The same click-to-connect behaviour, on an image port. The port has been tapped and the list shows every image node available to attach — each with its tag (서A01, 서A016…) and a checkmark where already linked. This dropdown is not unique to images or to the story node; it's how every port on every node offers its connections.

⚙️

The two models — main and sub

StoryEngine runs on two AI models working together under the hood.

User input
The text typed into the chat box.
Sub-model
Handles Full Story retrieval — and quietly does more. Its main job is semantic search of the Full Story space — the 30,000-token text field on story and character nodes, holding bulk worldbuilding and character data — pulling out the chunks relevant to the current moment. This is the only part of the system that works by meaning rather than exact wording; the internal method is undisclosed.

The sub-model is also understood to handle memory: summarising and managing the running conversation so older context stays usable. (This is the machinery the Info Management and Long-term Memory toggles in Advanced Settings switch off.) It's reportedly involved in variable management as well — worth knowing, since this side of the sub-model is easy to overlook and trips up new creators. (Reported by アヤイヤオ; the variable-management part isn't fully confirmed, and note the two-model split elsewhere in this guide describes variable update instructions as the main model's output.)
Macro Prompts
A separate, direct path — not the sub-model. Macro Prompt (lorebook) entries are keyword-matched and injected straight into the main context. When a registered keyword appears in user input, the matching entry is added — no model reads or reworks it in between, it's a rule-based trigger. max 5 injected at once Higher priority entries win the slots.
Main model
Handles generation. Always receives, fixed: story Core Context + prologue + character Core Context.
The Full Story chunks the sub-model retrieved, plus any keyword-matched macro (lorebook) entries, are added on top — and the response is generated from the combination.
Image tag output smile angry and variable update instructions are also the main model's job.
Output
Narrative text + image tags → rendered to screen.
💡
Two different retrieval paths — don't lump them together
Full Story goes through the sub-model: semantic search, fetched only when the situation calls for it. It matches on meaning.
Macro Prompts does not touch the sub-model: exact keyword matching, injected directly. It fires when a specific word shows up, nothing fuzzier.
And separate from both, Core Context is injected into the main model every single turn — that's where your hard rules go.

📋

Story node

The central node of the Canvas. Character, macro and achievement nodes all connect into it and get compiled together. What you write here reaches the main model first, at the highest priority.

You can create multiple story nodes — useful for chapter or scenario branching. Turn Is Start: Yes on for every node you want offered as an opening, and the reader chooses which one to begin from.
Story node panel showing Is Start, Core Context, Full Story, Prologue Message, Prologue Guide and Creator Notice fields
The story node, with its input ports down the left side. Those port labels — Trigger, Characters, Background Image, Macro Prompts, Update Rule, Status View, Achievement, Preset Notes — aren't just decoration. Click or tap one and a list of every node belonging to that category appears; pick one and it connects automatically. This exists because dragging wires by hand is miserable on mobile, so if you're building on a phone, connect this way instead.

The fields you actually fill in:

FieldDescription
Is Start Marks this node as a selectable starting point. Switch it on for each story node you want offered at the beginning — if more than one is set to Yes, the reader picks which opening situation to start from before the chat begins. This is how you offer several routes into the same story, so don't assume you're limited to one.
Core Context
(2,000 tokens base)
The hard-rules space. Directives the AI must always obey — SYSTEM_LAYER / WORLD_LAYER / DIRECTIVE and so on. The main model reads this before anything else.
The budget is 2,000 tokens by default, and grows if you enable toggles in Advanced Settings. A canvas showing 3,800 has +1,800 worth of toggles switched on.
Full Story
(30,000 tokens)
The sub-model's retrieval space. Worldbuilding knowledge, location details, per-scene setup — all the bulk goes here. Unlike Core Context it is not always injected; the sub-model pulls from it as the situation calls for. The internal search method is undisclosed.
Prologue Message
(700 tokens)
The opening scene shown on the chat start screen — the first thing a user sees on entry. But it isn't only for the reader: the AI reads it too, and treats it as established opening context — which characters are present, what's already been set in motion, whether a macro should fire from the very first turn. So write it as a scene that primes the story, not just a greeting.

A practical use of that: Prologue Guide is only 300 tokens, which gets tight. When first-turn setup won't fit there, creators often seed the overflow here instead — folding a hint or a bit of initial state into the prologue message, since the AI reads this anyway.
Prologue Guide
(300 tokens)
First-turn handling instructions given only to the AI. "Open the next turn this way," "initial variable values are these," and so on. Never shown to the user.
Creator Notice
(500 chars)
A note from you to your readers. Commonly used to state which models the story was tuned for and which ones misbehave with it — worth filling in, since readers can pick their own model.
🧭
Craft tip — the in-reply summary block, and why its position matters.

A common pattern is to instruct the model, from Core Context, to end each reply with a code block summarising the current state — stats, relationship values, what each character is thinking. This is not the Status View node, which is a separate side panel; this block is written by the model as part of its own output, because you told it to in Core Context.

Since a language model writes top to bottom, where you ask for that block decides what it can draw on.

At the end of the reply (the usual choice): the scene is already written by the time the model reaches the block, so the values are derived from the prose immediately above. State follows narration — the numbers describe what just happened.

At the start: the block is committed before the prose exists, so the figures come first and the narration is written to justify them. Neither is wrong — they simply run in opposite directions, and it's worth knowing which one you're asking for.
💭
Inner-thought lines do double duty. A "what the character is thinking" line inside that summary block reads as interiority to the reader — but functionally, it steers the next turn. Whatever the character is left thinking at the end of a response becomes context the following response is written against. Treat it as a steering handle, not just flavour: a thought that closes a door will narrow what happens next, and a thought that opens one will widen it.
↓ So why does Is Start have a "No" option?
Because a node set to No isn't unused — it's a branch destination you arrive at mid-chat. See Scenario branching below.

👤

Character node

One node per NPC. Appearance, personality, speech style, relationships — every piece of character information lives here. Connect it to a story node and the main model becomes aware of that character.

💡
Speech style goes directly inside the character node. There used to be a separate text node for it; it's since been folded in.
Character node showing Profile image, Name, Core Context and Description fields
The clearest way to hold the two fields apart: Core Context is what the main model reads every turn, Description is what the sub-model retrieves when relevant. (The labels in this screenshot were typed in by hand to illustrate that split — they aren't part of the UI.) Note the Emotion Image and Situation Image ports on the left.
FieldDescription
Name
(100 chars)
The character's display name. Non-Latin scripts are fine.
Core Context
(300 tokens)
Shown in the key-information panel. Keep it to essential attributes only — name, age, gender. The budget is small on purpose, so spending tokens carefully here matters.
Description / Full Story
(30,000 tokens)
The same sub-model retrieval space as the story node's, though it's understood to be classified differently internally (exact behavior undisclosed). Keep it to character-related material only — personality, speech patterns, behavior, backstory, relationships.
Show in character preview Whether this character appears in the preview section on the detail page. Usually left off for characters meant to be discovered in play.
title An internal code label, just for your own sorting. e.g. KMR
👥
Past 20 characters, not all of them load at once. A single session pulls in up to 20 characters automatically. If your story has 21 or more, only 20 are loaded per session — chosen at random — so a character you were counting on may simply not be present that session.

The reader-side fix is Always Load Character Info, in the User Notes menu: the reader can pin specific characters to load every time (up to 50). Two things worth knowing as an author: it's the reader who toggles this, not you — and each pinned character spends the reader's own token budget (the same 2,000 shared with User Notes and persona), by the per-character token amount shown next to each name. So a big cast that leans on this quietly costs the reader tokens.

The practical takeaway: if you can tell your story with 20 characters or fewer, do — it sidesteps the random-load problem entirely. Above 20, expect to guide readers toward pinning the essential few.
The reader's User Notes menu with an Always Load Character Info list, each character showing a token cost and an ON/OFF toggle, header reading 0 of 50 selected
The reader's view. Below their own User Notes field sits Always Load Character Info — a list of the story's characters, each with its token cost (225, 208, 212…) and an ON/OFF toggle, capped at 0/50 selected. This is the reader pinning who must always be present; every toggle they flip on draws from their shared token budget. (Screenshot kindly provided by NAFE, whose story actually runs a cast this large.)

📚

Macro Prompts (Lorebook)

Keyword-triggered injected memory. Write entries inside a macro prompt node, and when a registered keyword appears in user input, that entry's content is injected directly into the main context — no sub-model reads or reworks it in between. This is exact keyword matching, not similarity search: an entry fires when its trigger word shows up, nothing fuzzier than that.

Unlike story and character nodes, which are always present, the macro prompt is injected dynamically based on what's happening.

⚠️
At most 5 entries are injected in a single turn. Past that, higher Priority values win the slots. The more important the rule, the higher you should set it.
Three macro prompt nodes showing empty state, a new entry, and a filled entry
All three stages in one shot. Left: an empty node — "No macro prompt entries yet." Right: a fresh entry with blank Trigger Words. Bottom: a completed entry with the keyword Call_Keyword registered and prompt text written in. Note the Always toggle beside Trigger Words — switch it on and the entry injects every turn regardless of keywords, which costs you one of the five slots permanently.

What one entry consists of:

FieldDescription
Trigger Words
(up to 5)
The keywords that fire this entry. Add them one at a time; each becomes its own chip.
Always Injects the entry every turn, ignoring keywords entirely. Use sparingly — it permanently occupies one of the five slots.
Prompt Text
(300 tokens)
The actual content injected when the entry fires.
Priority Higher values win the five slots first. OOC and system rules are typically set around 99–100.
Duration (turns) How many turns the injection persists. Usually 1.
A macro prompt entry with the Always toggle switched ON and the Trigger Words field left empty
The Always toggle, switched on. Notice the Trigger Words field is empty — with Always: ON the entry needs no keyword, it's injected every single turn. This is how you pin a rule that must be present in every response (an OOC directive, a hard constraint), at the cost of one permanent slot out of five.
Feel free to create several macro prompt nodes and split them by purpose — an OOC-rules node, a worldbuilding node, an image-rules node. Much easier to maintain than one giant pile.
⚠️
Pick trigger words that won't collide with ordinary text. Because matching is literal, a common word as a trigger fires the entry constantly and at the wrong moments — a keyword that overlaps something the reader or the story naturally says will misfire and can throw the scene off. Favour distinctive tokens (a coined term, a rare compound) over everyday words. (Tip from アヤイヤオ, who got tangled up by exactly this.)
🔀
One more thing you can do with a keyword: reader-toggled "modes." Separate from the Always behaviour above — here the entry stays off until the reader types a specific keyword, then switches on. A common pattern is a distinctive trigger like !free mode with the mode's prompt in that entry. This overlaps with what preset notes do, and both are valid — the choice is a matter of taste. The practical differences are how many tokens it costs and where it lands in priority: a preset note spends the reader's own budget and reads at the bottom of the order, while a macro entry spends your node's budget and can be prioritised wherever you like. (Screenshots and this suggestion from Mukmul.)
A macro prompt entry with Always OFF and a keyword trigger of exclamation-free-mode, used as a mode toggle
A keyword-toggled mode. Always is OFF here and the trigger word is !free mode — the entry does nothing until the reader types that keyword, then switches on. The leading ! is just a convention to make the keyword distinctive and unlikely to fire by accident.

🖼️

Image node

Manages the image set shown for a character. Each image is bound to a tag, and the main model's tag output decides which image gets displayed. Image nodes connect to character nodes.

⚠️
The filename is the tag. There's no separate tag field to fill in — whatever the file is called becomes the tag. Name your files accordingly before uploading.
An empty image node beside a filled one showing Situation Image Tags and Paid Unlock Settings
Empty node on the left, populated node on the right. The uploaded image carries the tag smile under Situation Image Tags. Below it, Paid Unlock Settings — switch it on and readers spend credits to reveal that image (50 per image here).
Bulk tag editing panel with Bulk Tag Application, Add Images, Filter by Tag and CSV export controls
The bulk editor — worth opening early if you have more than a handful of images. Bulk Tag Application adds or removes a tag across every image at once, Filter by Tag narrows the view, and Copy as CSV / Copy Tags Only get your tag list out for editing elsewhere. Retagging fifty images one by one is a genuinely bad afternoon.

🗂️

Categorize Image Tags

Images on StoryEngine behave as an independent module, not an extension of your prompt. So for the AI to know which image suits which moment, you have to sort your tags into categories and write the descriptions yourself.

Found under the top menu: Canvas → Categorize Image Tags.

⚠️
Category descriptions must stay under 25 tokens. Longer descriptions simply don't work correctly.
Categorize Image Tags dialog showing an uncategorized smile tag and an empty category list
What it looks like before you've done anything. The tag smile sits on the left as an uncategorized situation tag, and there are no categories yet. Note the warning that appears underneath — "Uncategorized situation tags exist" — which is the platform telling you the AI has no idea when to use that image.

The order to do it in:

StepWhat to do
1. Create a category Type a name and add it. e.g. Emotions Locations Activities
2. Write the description In under 25 tokens, state when and in what situation the category applies. The AI reads this to decide which image to reach for.
3. Assign tags Add the tags from your image nodes into the matching category. e.g. Emotions → smile angry sad
💡
The category description is a live instruction the AI reads. Keep it short and unambiguous — "used when expressing emotion" is the right register. The better your categories, the more accurately images land.
Screen recording: opening the Categorize Image Tags panel, creating a category, writing its description, and assigning tags to it
The whole flow, start to finish. Opening the panel with uncategorized tags on the left, adding a category on the right, writing its description, and dropping tags into it. Watch the Uncategorized situation tags warning up top: it's there precisely because tags are still sitting unsorted, and clearing them is the goal.

🔢

Variable node

Stores a value tracked across the chat. Boolean, number and string types are supported. Variables are either read by a trigger node to test a condition, or displayed in a custom status view.

The normal pattern: variables usually don't go through a trigger at all. You pair a Variable node with an Update Rule node and hang them straight off the story node. Triggers and achievements are the extra branch you add only when you want a variable to become a milestone event.
Three variable nodes of type String, Number and Boolean feeding into a single Update Rule node
Three variables — A (String), B (Number), C (Boolean) — all feeding one Update Rule node. This is the shape most of your event work will take. One update rule can govern several variables at once; you don't need a separate rule per variable.
FieldDescription
Variable Name
(100 chars)
The variable's identifier.
A var_ prefix makes it readable from a status view HTML panel as {{var_NAME}}.
The prefix is only strictly required for status view display — without it, trigger and achievement wiring still works. But there's more to it (see the note below), so prefixing is worth doing as a habit.
Variable Type Boolean Number String
Initial Value Starting state. Boolean defaults to No, Number to 0, String to empty.
title Internal code label. Matching it to the related trigger and achievement makes them easy to pair up later. e.g. A1
⚠️
Keep variable names clearly distinct from one another. Names that look alike can bleed into each other — updates meant for one variable landing on another, values quietly getting crossed. Give each variable a name that can't be mistaken for its neighbours (not affection / affection2, but names that read differently at a glance), and the problem doesn't come up.
🔎
Where the var_ prefix actually comes from. It isn't in the official documentation, and older builds didn't use it — it appears to have been introduced fairly recently. Looking into it: the prefix seems to exist to keep variable data from getting crossed during compilation as canvases grew larger and more crowded. In other words it's the same collision problem as above, addressed with a naming convention. Things still run without it, but prefixing is recommended. (Not officially confirmed — a definitive answer would need to come from the platform. Flagged by アヤイヤオ, checked together.)

Trigger node

Fires an achievement when a variable meets a condition. It takes the story node and a variable node as inputs, and signals the connected achievement node when the condition is met. You only need a trigger when you want an achievement to unlock. A variable that merely tracks a value doesn't need one.

💡
How the event system is assembled: story node + variable node + trigger node + update rule node, with the achievement node added as needed. The flow below is the branch that goes all the way to an achievement.
Story node
+
Variable node
Trigger node
Achievement (optional)
Variable node connected through a trigger node into an achievement node, with an update rule above
The full chain, wired up. Variable C (Boolean, initial value No) runs into a trigger watching for the value Yes, which fires the achievement node on the right. The Update Rule node sits above, connected separately — it's what actually moves C from No to Yes during play.
FieldDescription
Variable to watch The variable this trigger monitors. Must match the name on the connected variable node.
Value The trigger fires when the watched variable reaches this value. For a Boolean, usually Yes.
title Use the same label as the paired variable and achievement. e.g. A1

🏆

Achievement node

A milestone shown to the reader when its trigger fires. Connect the achievement node back into the story node so the story itself can react to it having been earned.

A production canvas with four variable-to-trigger-to-achievement chains running in parallel, each achievement carrying its own image, name, description and priority
A real canvas, not a demo — four achievement chains running side by side. Each row is the same shape repeated: a Boolean Variable → a Trigger watching it for Yes → an Achievement holding its own artwork, name and description. The variable names are blurred by the author; what matters here is the repetition. This is what a story with several unlocks actually looks like once it's built, and it's why matching title labels across each set is worth the effort — at this density, wires alone won't tell you which trigger belongs to which achievement.
FieldDescription
Achievement Image Optional artwork shown with the unlock. Click or drag-and-drop to set it.
Achievement Name
(100 chars)
The name the reader sees.
Description Flavour text displayed when the achievement is earned.
Display Priority Higher numbers appear first in the achievement list. Useful for putting story-critical unlocks at the top.
Hidden achievement Hides both name and description until earned. Recommended for anything that would spoil the story.
Give the variable, trigger and achievement of a set the same title label (A1, A2, A3…). Once the canvas gets busy, this is the difference between reading your own structure at a glance and hunting through wires.

🔀

Scenario branching — multiple routes through one story

🙏
This technique was reported by ㅇㅅㅇㅇㄴㄷ, not worked out by me. Thank you. (Their page shows a Korean handle because an earlier error wiped the English one.)

A story node set to Is Start: No isn't a leftover — it's a destination you arrive at partway through a chat. Wire a trigger into one, and when that trigger fires, the story hands off to it. The practical result is a visual-novel style route select: one work containing several distinct paths.

Variable
+
Update Rule
Trigger
Story node (Is Start: No)

It's the same chain you already use for achievements, with one difference: the far end is a story node instead of an achievement node.

A canvas showing an opening story node, two variables with update rule and triggers, feeding two separate story nodes set to Is Start No
Two routes wired from one opening. On the left, the starting story node (Is Start: Yes). In the middle, string variables part1 and part2 with an update rule, each feeding a trigger that watches for a specific value — P1 and P2. On the right, two story nodes set to Is Start: No, one per route. This diagram was assembled from a verbal description rather than a verified build — read it as the shape of the thing, not a blueprint to copy pin-for-pin.

How it plays out in practice:

StepWhat happens
1. Offer the choice In your opening scenario, give the reader a way to pick. That might be an instruction to type a specific keyword, an in-character question, a menu written into the prologue — whatever suits the story. The reader's input is what drives this, so it has to be discoverable.
2. Update the variable Your update rule catches the input and writes the corresponding value into the variable. In the screenshot these are strings — part1 starting at wait, changing to P1 once the choice is made.
3. Trigger fires The trigger watching that variable sees its value and fires, exactly as it would for an achievement.
4. Route opens The story node behind the trigger takes over, and the chat continues from that node's context instead of the original one. That's the branch.
💡
Give each route its own variable and trigger, and label them in matching sets (P1, P2…) the same way you would for achievements. A branching canvas gets crowded fast, and the labels are what keep it readable.
⚠️
This section is newer and less tested than the rest of this guide — it comes from a single report rather than from repeated building. If you try it and find that something works differently, please say so.

📝

Preset Notes — reader-toggled prompt modules

Preset notes are optional prompt blocks that you write and the reader switches on. Each one has an icon, a title, a short description the reader sees, and the prompt text that gets injected when it's enabled. Think of them as opt-in modifiers for your story — an extra mode, a content emphasis, a tone shift — that the reader chooses rather than you forcing.

The preset note node on the canvas, showing Icon, Title, Description, Prompt and Priority fields for two notes, with the prompt bodies deliberately blurred
Author side — the preset note node on the canvas. Each note is an Icon, a Title, a Description (what the reader sees), a Prompt (what actually gets injected, out of 500 tokens), and a Priority. The prompt bodies here are blurred on purpose — those are the author's own, and a real tutorial build would leave them empty for you to fill in. The point is the field layout, not the contents.
⚠️
The important catch: preset notes spend a token budget the reader also needs for other things. The reader gets an allowance of 2,000 tokens, shared between their User Notes and their User Persona. Enabling a preset note draws from that same pool. Past 2,000, the usage fee rises by 10% for every additional 600 tokens.

So a heavy preset note doesn't just crowd out the reader's own notes and persona — it can push them into paying more. (Budget figures reported by ㅇㅅㅇㅇㄴㄷ, who checked them after this section first went up with a wrong number in it.)
🧮
Worked example, using the two notes in the screenshots below. Sweat Overdrive is 368 tokens, Event Overlord 408. Turn both on and that's 776 of the shared 2,000 gone before the reader has written a word of their own persona or notes. A few more notes on top, or a reader with a detailed persona, and they cross the line into the higher fee. Every token you put in a preset note is a token you're potentially asking the reader to pay for.

Two consequences fall out of that, and both matter when you're authoring:

ConsequenceWhat it means for you
Can't all run at once You can define up to 10 preset notes, but the reader can't enable all of them together — each one consumed comes out of a finite budget, so they'll run out of room. Design them as choices, not a stack meant to be fully on.
Keep each one lean A heavy preset note (real ones run ~370–410 tokens) eats a sizeable chunk of the shared 2,000 on its own. Several of them and the reader is well into that budget before writing a single word of their own persona. If a note has to be big, make sure it earns the cost.
The reader-side User Notes menu, showing a personal notes field above a list of preset notes with ON/OFF toggles and per-note token counts
Reader side — the same notes, as a reader sees them. Up top is their own User Notes field with its token counter. Below, the author's preset notes — each with an ON/OFF switch, a View full link so the reader can read the whole prompt before enabling, and its token cost (368, 408). The header reads 0/10 notes active: ten slots exist, none are on here. That token counter at the top of the reader's own field is the meter that matters — it covers their notes and persona together, and preset notes draw from the same pool.
FieldDescription
Icon A small emoji shown next to the note in the reader's list.
Title The note's name, as the reader sees it in the toggle list.
Description A short line explaining what enabling this note does — shown to the reader to help them decide.
Prompt
(500 tokens)
The text injected into context when the note is on. This is what actually spends the reader's tokens.
Priority Ordering value among enabled notes.
💡
Preset note input lands at the bottom of the priority order — it's read after your core directives and character data, not ahead of them. So a preset note nudges the story; it won't override rules you've set higher up. Keep that in mind when you write one: phrase it as an addition, not a contradiction of your core context.

🔧

Other nodes

Supporting nodes you'll meet once the basics are in place. These are covered lightly on purpose — they're best learned by clicking on them and seeing what happens.

Update Rule Milestones for your variables
Defines the milestones a variable moves through. Tells the AI when, under what conditions, and by how much to update a variable. Pairs with variable nodes off the story node, and is heavily used alongside a status view. 400-token budget. e.g. affection, fatigue, location.
Status View Custom HTML panel
A status panel you write in HTML/CSS/JS. Read live variable values with the {{var_NAME}} syntax. Only variables carrying the var_ prefix are visible here. Don't confuse this with the summary code block some stories print at the end of each reply — that one is written by the model because Core Context told it to, and is covered up in Story node.
Background Image Scene backdrop
Connects to the story node to set the backdrop behind the chat. Go press it and see.
Annotation A note to yourself
A canvas sticky note — nothing more. It has no ports, so it connects to nothing and the AI never reads it. Purely for leaving yourself a comment on the canvas (400 characters).

This is what became of the old Text node. That one used to have a port and fed the character node's system part (speech style and the like); that role has since been folded into the character node itself, and the leftover node was repurposed into this note-only Annotation. If you remember a connectable Text node, this is where it went.
The old Text node, which had a Text output port wiring into a character node's system section
Then. The old Text node — note the Text port on the right, wired into the character node, carrying a speech-style definition (300 tokens). The author will admit this screenshot is from an embarrassingly old build of their own. 🙈
The current Annotation node, with no ports and a 400-character note field
Now. The same node today: renamed Annotation, no port at all, and measured in characters (400) rather than tokens. A note, not a wire.
🔍
Anything not documented here is genuinely worth just poking at. Nothing on the Canvas is destructive to open, and half of what KR creators know was learned exactly this way.

⚙️

Advanced Settings

A panel that switches off parts of StoryEngine's built-in behavior. Every toggle is OFF by default, and OFF means the feature is in use. Switching one ON disables the thing named. Read them literally — "Turn off X" set to ON means X is now off.

⚠️
Community knowledge, not official. The platform has never fully documented what each switch removes internally, and some of it is deliberately undisclosed. What follows is what KR creators have pieced together from actual use. Expect gaps.
Advanced Settings panel with eight toggles and a token bonus counter at the top
Note the counter at the top: "Additional tokens for core prompts: +1,800." That figure is the sum of the three toggles switched on here — Content Policy (+800), Shorten Narrative Instructions (+500), Emotion Images (+500). Turning off a built-in feature frees the space its prompt occupied and hands it back to your Core Context.
🧮
This is why Core Context budgets differ between canvases. The baseline is 2,000 tokens. A screenshot showing 3,800 simply has +1,800 worth of toggles enabled. Your own number depends entirely on what you've switched on — so don't treat any single figure you see online as the real limit.

Every bonus below was measured one toggle at a time. Switching on all seven that carry a bonus adds +5,500, which takes Core Context from 2,000 up to 7,500 tokens — nearly four times the default. Use Legacy Image Tagging changes no budget at all, since it swaps a method rather than removing a prompt.
ToggleWhat switching it ON does
Turn off Info Management +800 Stops the system auto-managing conversation memory. In practice it also disables the retrieval that keeps older context available, which is the larger consequence. Readers tend to hit long-term memory problems partway through a chat. Leave it alone unless you know exactly why you want it off.
Turn off Long-term Memory +1,200 The chat continues on recent messages only, without drawing on the story summary. Be aware: the observable symptoms overlap heavily with Info Management above, and the two have never been cleanly told apart from the outside. Treat them as related rather than independent.
Turn off Macro Prompts +1,200 Disables macro prompts — meaning your macro prompts stop firing entirely. Unambiguous, unlike the two above.
Turn off Content Policy +800 Disables StoryEngine's default content moderation and safety guidelines. Conceptually paired with Shorten Narrative Instructions below — both strip out vendor-supplied baseline prompting. Largest token refund of the set.
Platform rules still apply either way. The toggle changes prompting, not your obligations — regional title restrictions, terms of service and moderation of published work all remain in force.
Shorten Narrative Instructions +500 Uses a condensed version of the narrative engine prompts. These vendor defaults handle plot scaffolding and general storytelling posture, and they're deliberately broad — which suits most creators fine. If you're writing your own tight core logic, though, that generic layer works against you. Commonly enabled by creators doing heavy custom prompt work.
Turn off Emotion Images +500 Stops emotion image cues during character dialogue. Normally the character profile area calls an image whenever an emotion is detected in the exchange. That detection is computationally expensive, and creators who don't need per-emotion portraits often switch it off for that reason alone.
Turn off Situation Images +500 The same idea applied to situation image cues during narration, rather than character emotion.
Use Legacy Image Tagging no change Don't. Reverts to the old manual-description tagging method; output quality and accuracy are both worse. The real cost is that failures become unexplainable — calls that look entirely correct still don't behave, with nothing telling you why. Leave this off.

🚀

Publish settings — the page outside the Canvas

These fields live outside the Canvas and don't affect the AI at all. They're the storefront: what a reader sees before they ever press start. Most creators ignore this page entirely until the Canvas work is finished, which is why it's last here too.

⚠️
The numbers below — file sizes especially — get changed by the platform fairly often. Treat them as "last confirmed," not as law. Corrections are very welcome.
The publish settings page showing Thumbnail, Title, Brief Introduction, Description, Tags, Creator Settings, Intro Video and Add Collaborators
The whole publish page in one view. Thumbnail and Creator Settings run down the left, everything else on the right. Note the upload box under Intro Video spelling out its own limits — MP4, max 200MB, max 2min — and the Add Collaborators field, which takes a StoryEngine account email.
FieldWhat to know
Title The story's name. If you plan to localize: on the KR side, explicitly crude or vulgar phrasing in a title is not permitted. Pick something that survives the trip.
Brief Introduction 40-character limit. It's a one-line hook, not a summary. Easiest to write last, once you know what the story actually became.
Description Supports a minimal subset of Markdown: bold, a little font-size control, simple tables, and externally hosted images. Don't expect full Markdown — anything fancier won't render. Images must be hosted elsewhere and linked in.
Tags You can dump in every tag across every supported language at once. The platform automatically surfaces only the tags matching the viewer's language, so there is no downside to tagging in all of them. Do it.
Thumbnail 4:5 ratio. WebP uploads are allowed up to 5 MB (raised from the old ~2–3 MB ceiling in a mid-2026 platform update). GIF was last confirmed near 10 MB. Note the platform's own caveat: high-file-size or multi-frame images may lose some quality in the shrunk thumbnail shown on the main screen. If an upload fails without explanation, size is still the first thing to check.
Intro Video MP4, max 200MB, hard 2-minute cap. No leniency on the length — trim before uploading.
Add Collaborators Enter another creator's StoryEngine account email to bring them onto the work. You control whether they get Canvas access, and revenue can be split in 10% increments.
Creator Settings Chooses which collaborator is shown as the representative creator. Takes a creator nickname or OID.
StoryEngine Original An opt-in exclusivity designation for works provided exclusively to StoryEngine. The terms were overhauled in mid-2026 — if you've read older guidance describing a percentage-point settlement bonus, that is no longer how it works. The wording below was cross-checked by a creator in the English-language region and came back identical, so it isn't KR-only.

Activating: switch it on before the first upload, or within 6 hours after. Limited to 2 works per month, and a collaborative work counts against every participant's monthly limit.
Reward: paid at fixed milestones rather than as a rate bonus — KRW 100,000 at 10,000 eligible chats, plus a further KRW 200,000 at 50,000, divided according to the work's saved revenue shares. Only chats that happen after activation count, so activating late costs you everything before that point.
Locked for 180 days: you cannot delete the work, make it private, turn Original off, or upload it elsewhere. Collaborators and revenue shares also cannot be changed while Original is active — settle those before you activate.

Do not try to game this. The operations team has stated plainly that workarounds — publishing elsewhere first and staggering the upload here, or re-uploading the same build under a different name — result in a ban, no exceptions.
🔞
Content rules for thumbnails, titles and tags differ by region — and they're easy to break by accident.

This trips people up constantly: a work gets its main-page visibility pulled, or gets flagged, and the creator didn't know a rule existed. The platform operates under different legal environments in different regions, so the exact rules are not the same everywhere. The single most important habit is to read the activity guidelines for your own region before you publish — the summary below is a starting point, not a substitute for the current official text.

— Korea (KR) —
Based on the RPLAY activity guidelines. A thumbnail that hits any of the following has its main-page exposure restricted:
  • Thumbnails should be composed mainly of the upper body.
  • No exposure of genitals, pubic hair, or anus.
  • No nipple exposure in photorealistic images.
  • No depiction of semen or semen-suggesting fluids.
  • No images depicting or evoking direct sexual intercourse (whether mosaic-censored or not).
  • No dildos / genital-shaped sex toys.
  • No copyright-infringing images; nothing excessively provocative, hateful, or discriminatory.
Two things creators keep getting wrong here: first, a mosaic or blur is not enough — if an angle makes some exposure unavoidable, you must paint it out so the outline is completely gone (a solid black or white fill, not a mosaic). Second, and more simply: a thumbnail that just openly shows genitals is not allowed, full stop.
Titles and hashtags have their own restricted-word and required-tag lists (certain explicit terms restrict main-page exposure; certain special settings and identity tags are required). Read the current guideline text for the specifics — the lists change.

— Japan (JP) —
When asked (last year), the answer given was that standards follow published-media (publication) censorship norms. That's a different bar from KR, and it may have shifted since. Check directly against current publication standards before you publish rather than assuming the KR rules carry over.

— English-speaking region (EN) —
There are almost certainly applicable laws and platform rules here too. The specifics aren't spelled out in this guide, so confirm your own region's rules before publishing — "it wasn't removed last time" is not a rule.

Why this matters beyond your own account: content that breaks the law in a given region puts the platform itself at legal risk, which is exactly why these regional rules exist and why they're enforced. Following them protects the space everyone publishes in. These specifics are "last confirmed," not official text — when in doubt, the platform's own current guidelines win.
🌏
Yes, these Original terms are the same for you. The milestone amounts are quoted in KRW, which reasonably raises the question of whether creators outside Korea see something different. They don't. Scoot, a creator working in the English-language region, read the panel on their own account and the wording came back identical — same eligibility, same 6-hour activation window, same 2-per-month limit, same KRW milestones, same 180-day lock. Shared here with their permission; thank you.

To be precise about what this is: a creator-to-creator cross-check, not a statement from the company. It's good evidence that the panel reads the same across regions, but if you spot a difference on your account, please say so.
🚨
Multi-language releases — read this before you publish. Localized text does not apply until you actually press the upload button. Half-saved states are easy to create without noticing, so keep Publicity set to Private until every language is uploaded and confirmed, then flip it public once everything is in.
🔶
A recent patch made those "half-saved" states visible. Each language has its own independent canvas and compiles separately, and the language tabs now carry a small status badge: an orange (!) means that language's canvas has unsaved changes and needs compiling, and a red (!) means it has an error. Before this there was no indicator at all — you just had to remember. Now, if a tab is wearing an orange mark, that edition isn't fully saved yet; clear every badge before you rely on a language being live. (Flagged by トリ(STORY ENGINE).)
Language tabs KO, EN, JP with an orange exclamation badge on the EN and JP tabs indicating those canvases need compiling
The new per-tab status badge. Here the EN and JP tabs each show an orange (!) — those canvases have changes waiting to be compiled. Because each language is a separate canvas, the marks are per-tab: clearing one doesn't clear the others.

The same badge now shows up in your creator work list too (a very recent addition — it wasn't there earlier the same day). So you can spot which works need attention without opening each canvas: an orange (!) beside a work means it needs compiling, a red (!) means it has an error. Same colour meaning as the tabs, just surfaced one level up.

A work in the creator list with a red exclamation badge beside its thumbnail, indicating an error
Red (!) in the work list. This work has an error that needs fixing.
A work in the creator list with an orange exclamation badge beside its thumbnail, indicating it needs compiling
Orange (!) in the work list. This one just needs compiling — unsaved changes waiting.
💡
Ordinary practice among KR creators: tag in every language you can, keep the thumbnail comfortably under the stated cap so a limit change doesn't break it later, and settle the collaborator revenue split before publishing rather than after.
🐟
That's the whole tour. If something here turns out to be wrong — and some of it will, the platform moves — please tell me: open an issue on GitHub. Corrections and measurements both go straight into the next version, credited.

Not comfortable writing in English? Open the issue in your own language and say which one it is — Korean, English, Japanese, and Spanish are all fine, and I'll do my best to reply in the language you wrote in. A rough machine translation is completely welcome too; I'd rather have the report than have you skip it over the language.

Now go open the Canvas and press things.
🙏

Contributors

Most of what's accurate in this guide got that way because other creators took the time to correct it, test it, or translate it. Named here with thanks:

ㅇㅅㅇㅇㄴㄷScenario-branching technique; corrected the reader token budget (2,000 shared with persona).
ScootCross-checked the StoryEngine Original terms from the English-language region.
アヤイヤオSub-model's memory/variable roles; the token-counter tip; prologue message doubling as AI-read context; and the port-connect list being universal across nodes; distinctive trigger words.
yatomingNative-speaker review of the Japanese edition's phrasing.
夢見月ひいなCaught the Original lock period changing from 90 to 180 days.
MukmulScreenshots for the Always toggle and using a macro keyword as a mode switch.
NAFEScreenshot of Always Load Character Info from a 20+ character story.
トリ(STORY ENGINE)Flagged the new compile-status badge on the language tabs. (Not an official account, despite the name.)

If you reported something and aren't listed, or want your name shown differently, tell me — the omission is an oversight, not a slight.

🐟Made with Frozen_Tuna🐟 🐟