Node fields
Fields on one dialogue node. Script and JSON describe the same object — Story nodes.
{
"id": "park",
"talking": "hana",
"text": "Hello.",
"commands": [{ "type": "bg", "value": "street" }],
"next": "after"
}
Typical node
Common shape authors actually use (omit unused keys):
{
"id": "park",
"talking": "hana",
"label": "Hana",
"text": "Hello.{@c1} Ready?",
"set": { "met_hana": true },
"commands": [
{ "type": "bg", "value": "street", "transition": "fade", "duration": 0.5 },
{ "type": "char", "name": "hana", "position": "left" }
],
"flow_commands": [
[{ "type": "sfx", "value": "click" }]
],
"exit_commands": [
{ "type": "char", "name": "hana", "show": false }
],
"exit_delay": 0.3,
"next": "after",
"choices": {
"items": [
{ "text": "Stay", "target": "stay" },
{ "text": "Go", "target": "leave" }
]
}
}
| Zone | Keys |
|---|---|
| Identity / speech | id, talking, label, text |
| Enter | set, commands |
| Mid-line | flow_commands (+ {@cN} in text) |
| Leave | exit_commands, exit_delay |
| Branch | next, next_if, choices, input |
| Body links | text_metas |
| Timing / panel extras | auto, panel, panel_id, … (below) |
Script side-by-side: Story nodes · script.txt syntax. Batches: Command flow.
Usually you need
| Key | Type | Default | Effect |
|---|---|---|---|
id | string | auto _N | Node id (start = New Game entry; omit/_N → first moment is used) |
text | string | — | Dialogue body |
talking | string or string[] | — | Who is speaking this moment (one id or several) |
commands | array | — | Run on enter — Command flow |
next | string or null | next in file / null | Linear target |
choices | object | — | Menu — Choices |
input | object | — | Text field — input |
set | object | — | Flags on enter |
All fields
| Key | Type | Default / omit | Effect |
|---|---|---|---|
id | string | auto _N | Node id; start is the default New Game entry (Scenes and jumps) |
text | string | — | Dialogue (BBCode + {@…} + {flag}) |
label | string | — | Speaker plate override |
talking | string or array | — | Speaker id(s) |
talking_anchor | string | — | Initial focus when multi-speaker |
set | object | — | Flags on enter; "= expr" = expression |
commands | array | — | Enter commands |
flow_commands | array | — | Batches indexed by {@cN} (1-based) |
exit_commands | array | — | Run on leave |
next | string or null | auto | Linear target; NEXT / END / START keywords |
next_if | array { expr, then } | — | First truthy, else next |
choices | object | — | Choices |
input | object | — | input |
auto | number ≥ 0 | — | Auto-advance seconds ([auto N]) |
exit_delay | number ≥ 0 | 0 | Seconds after exit_commands before next node |
text_metas | object | — | Map [url=key] → action — Flow tags |
panel | string | resolve chain | Preset override |
panel_id | string | from talking → "main" | Target panel instance |
text_mode | "replace" | "append" | "plates" | "replace" | Content mode — Appending text |
append_direction | "down" | "up" | "down" | Append / plates direction |
append_gap_lines / append_gap_px | number ≥ 0 | 0 | Append gaps (append_gap_lines ignored in plates) |
plate | string | — | Plate name for text_mode plates this moment — Theme: panel → Plates |
hide_panel | bool | false | Hide the routed dialogue panel for this node (wins over routing show) |
hide_continue / hide_back | bool | false | Hide nav chrome |
driver_typing | bool | true (unless silent) | Typing driver / beep |
panel_shader | object or null | absent = clear | Per-node panel shader |
panel_presence_mode | enum | — | One-cycle presence |
panel_non_talking_mode | "hide" | "readonly_last_text" | — | One-cycle |
panel_readonly_style_key | string | — | One-cycle readonly style |
labelplate | object | — | Same keys as labelplate command |
text_ref | string | — | Strings catalog key |
text_from | string | — | Copy text from another node id |
Panel routing for presets / presence: Panel routing. panel_shader absent clears (unlike sticky panel / bg shaders).