// text-based narrative RPG engine
BLACKBOX
Build worlds. Write choices.
Let the engine handle the rest.
Blackbox is a pure-logic engine for text-based narrative RPGs. It loads JSON scenario content, tracks every branch and player decision, runs skill checks, and returns clean read-only views — your host app renders exactly what it wants.
Blackbox separates story logic from presentation entirely. Authors write branching scenarios in JSON — chapters, nodes, gated choices, effects. The Rust engine processes commands, advances state, and returns snapshots. No I/O, no rendering, no audio. Your host owns all of that.
Everything the story needs.
Nothing it doesn't.
Node-Based Story Graph
Scenarios are graphs of nodes. Each node carries narrative blocks — dialogue with speaker and emotion, internal monologue, stage directions, and plain paragraphs. Nodes link via choices; the engine walks the graph and returns a view.
Gated Choices
Choices lock behind stat thresholds, flag conditions, item ownership, and visited-node checks. Disabled reasons surface to the player automatically. Per-condition gates can be combined with AND/OR logic.
Skill Checks
D20 rolls: stat + roll vs. difficulty class, with advantage and disadvantage. Seeded deterministic RNG makes every playthrough reproducible. Success and failure branch to different nodes with independent effects.
Rich Persistent State
Stats, inventory items, boolean flags, character relationship scores, and visited-node history. All state serialises to JSON for multi-slot saves. Text blocks can interpolate any live value: {stat.logic}, {item.key_card}.
Cross-Platform Core
One Rust codebase compiles to WASM for browsers via wasm-bindgen, a stable C ABI for iOS and Android via cbindgen, and a native binary for CLI tooling — all from the same engine logic.
Reusable Content
Library snippets let authors write a text block once and reference it from any node. Node templates via $extends share base choices and effects. Item and character catalogs are shared across the full scenario.
Ship with confidence.
Three dedicated tools cover the full author workflow — from writing to validation to production build.
Linter
Validates scenario bundles before they ship. Catches broken node references, dangling choice targets, missing asset files, malformed gate expressions, and unreachable nodes. Nine rule categories, JSON output, CI-ready exit codes.
Simulator
Headless multi-threaded playthrough engine. Explores every reachable path in the scenario graph — confirms all endings are reachable, reports narrative hot paths and split-candidate nodes, detects dead ends. Run with --check in CI for a hard gate.
Bundler
Compiles scenario JSON and raw assets into optimised .box binary bundles. Transcodes PNG→WebP and WAV→Opus (platform-specific bitrates). Converts all JSON documents to MessagePack for lower runtime parse cost. Splits output into a shared bundle and per-chapter bundles so players only download the chapter they need.
Pure logic. Zero coupling.
The engine does one thing: take a command, advance state, return a view. No I/O, no rendering, no audio. Your host app owns all of that — the engine just tells it what changed.
JSON scenario bundles — chapters, nodes, choices, effects, audio cues
Rust core — state machine, effect evaluator, RNG, validation
Read-only snapshots — narrative, choices, stats, inventory, rolls
Your app — React, Swift, Kotlin, terminal, anything
One engine. Every surface.
Web
WASM + ReactShip a full browser client. The wasm-bindgen binding crosses the JS boundary with delta-encoded views for minimal allocation overhead.
iOS & Android
C ABIA stable C foreign-function interface lets Swift and Kotlin call the engine directly — no extra runtime, no managed heap, pure native performance.
CLI & Tooling
Native binaryRun scenarios in the terminal. Pipe JSON in, get JSON out. Pairs with the linter and simulator for fully automated CI pipelines.
Author everything
in one place.
Blackbox ships with a desktop editor for building scenario content — node graphs, item libraries, chapter structure, and a live simulator that runs your story end-to-end before it ships.

Author in JSON.
Play anywhere.
Scenarios are plain JSON — chapters, nodes, conditional text, gated choices, effects. The linter validates your content before it ships.
{
"id": "investigation_begin",
"narrative": [
{
"text": "The corridor is silent. Water drips somewhere below."
},
{
"speaker": "CASE-7",
"text": "Your access log shows no movement on this floor for fourteen months.",
"emotion": "neutral",
"side": "left"
}
],
"choices": [
{
"text": "Check the security terminal.",
"effects": [
{ "type": "stat", "key": "logic", "delta": 1 }
]
},
{
"text": "Proceed to the lower ward.",
"requires": { "stat": "conviction", "gte": 3 }
},
{
"text": "[SKILL CHECK] Force the door. (STR · DC 14)",
"check": { "stat": "strength", "dc": 14 },
"on_success": "lower_ward_forced",
"on_failure": "door_holds"
}
]
}

