How a Script Becomes Data a Program Can Read: Nodes, Options, Conditions, and Outcomes
Connecting a script to a program is about establishing a stable narrative data contract, not copying a Word file into JSON. Each node describes what plays and when interactions appear; each option describes its display conditions, player intent, state outcomes, and target node. Text, media, and logic reference one another, while each has its own traceable versions.

Introduction
Connecting a script to a program is about establishing a stable narrative data contract, not copying a Word file into JSON. Each node describes what plays and when interactions appear; each option describes its display conditions, player intent, state outcomes, and target node. Text, media, and logic reference one another, while each has its own traceable versions.
Start with Stable IDs
Chapters, scenes, nodes, options, and assets all need unique IDs. Display titles can change, but once an ID enters production, it must not be reused. For example, a node might be C02_S04_N030, an option C02_S04_N030_O2, and a video C02_S04_N030_main_v07.mp4. The program, subtitles, analytics instrumentation, and bug reports all use the same identifier.
IDs do not include actor names, emotions, or final dialogue, because these can change. Retired IDs remain in the change log to prevent old saves or logs from mistakenly pointing to new content.
Give Each Part of the Node Structure a Single Responsibility
Node data can include id, media, entryConditions, onEnter, interactions, onExit, fallback, and tags. Media fields reference the asset manifest without embedding absolute local paths; conditions only read state; effects only write to permitted state.
{
"id": "C02_S04_N030",
"media": "VID_C02_S04_N030_MAIN",
"entryConditions": ["evidence_recording == true"],
"interactions": ["C02_S04_N030_O1", "C02_S04_N030_O2"],
"fallback": "C02_S04_N040"
}
The example only illustrates these boundaries; the actual format can be JSON, a spreadsheet export, or a narrative script. What matters is that each fact has a single authoritative location.
Record Both Display Rules and Consequences for Options
An option needs a text key, visibility conditions, selectability conditions, timing rules, state effects, and a target node. When it is visible but unavailable, give the player a reason; when it is completely hidden, do not leave a blank button. Use localization keys for text, rather than treating the original Chinese sentence as a logical condition.
Effects should preferably use restricted operations, such as setting a Boolean value, adding resources, or changing a relationship stage. Do not allow arbitrary scripts to hide inside each option, or the writers’ data will become an unauditable program. Delegate complex behavior to the runtime through named commands.
Conditions Must Be Verifiable and Explainable
Conditions reference official names from the variable table and restrict comparison types. Do not mix Boolean values with strings; enums accept only valid values; numbers have upper and lower bounds. During export, the editor or build script checks for unknown variables, unreachable nodes, loops without exits, and missing targets.
Break complex conditions into named rules. For example, can_publish_truth consists of having all key evidence, the journalist still cooperating, and sufficient resources. Test logs must output both rule results and underlying values to explain why a player did not see a particular option.
Decouple the Media Manifest from Narrative Data
Nodes reference only logical asset IDs; the asset manifest then maps these to files for different platforms, languages, and quality levels. This means changing an edit from v06 to v07 does not require changes to branching logic; using a lower bitrate on mobile does not require duplicating the nodes either.
The manifest records at least the file, checksum, duration, resolution, audio tracks, subtitles, version, and review status. The runtime can verify checksums and durations before loading to reduce the chance of incorrect or truncated media entering the release package.
Define a Clear Execution Order
Specify the order of entering a node, preparing media, playback, displaying options, submitting a choice, applying effects, and leaving the node. Whether state is written before or after the transition affects the next node’s entry checks. Treating choice submission as an atomic transaction is recommended: verify that the option is still selectable, write the outcome, record the log, and then transition; on failure, leave state unchanged and provide a recovery path.
Timeouts, skipping, loading saves, and repeated clicks must also pass through the same state machine. Lock the button immediately after submission to prevent a double-click from writing twice; when exiting and re-entering, restore based on the committed marker instead of awarding rewards again.
Establish Data Validation and Readable Logs
Every build automatically checks that IDs are unique, references exist, there is at least one exit, variable types are correct, localization keys are complete, and media can be found. Classify warnings and errors by severity: a missing optional note can produce a warning, but a nonexistent target node must block the build.
Runtime logs use structured events to record the session, node, option, summaries of state before and after, time, and version. Logs must not contain unnecessary personal information; debug builds can be more detailed, while production analytics events follow privacy and consent requirements.
Enable Review by People Who Do Not Program
Machine-readable does not mean difficult for people to read. Generate node tables, branching diagrams, and playable previews from the same data, so writers can check dialogue, producers can check assets, and testers can check paths. Mark any manually generated copies as unsuitable for writing back to the source, to prevent multiple people from maintaining multiple versions of the truth.
Next step: choose ten nodes to define a minimal data schema, and create one valid example and three deliberately invalid examples. Import the full script only after the build checks correctly catch unknown variables, dangling exits, and missing media.


