Git-native narrative design
for story-driven games
Schema-first. Engine-agnostic. Your story is plain JSON in your repo — no database, no export step, no proprietary format between your writers and your game.
Your story is files
Every character, dialogue, and quest is a human-readable JSON file the visual editor reads and writes directly. Git is the single source of truth — which means narrative gets branches, diffs, reviews, and CI, just like code.
{
"id": "dlg_wren_cornered",
"title": "Wren — The Yard",
"speakerId": "npc_wren",
"offer": {
"when": { "type": "flag", "flag": "knows_wren_dismissed", "value": true }
},
"entry": "node_corner",
"nodes": [ … ]
}$ git diff data/dialogues/dlg_wren_first.json "text": - "I sell tinctures. Nothing stronger." + "I sell tinctures, magistrate. Nothing stronger — + nothing that would do *that* to a man." One line of dialogue changed. One line in the diff. Review it in a pull request like everything else.
Built around the way stories actually branch
A visual editor for the whole narrative layer — not just dialogue trees. This is it, editing the demo mystery:
The dialogue canvas — a suspect's confrontation scene, with skill-check routes (green success / red failure) and live pacing analysis.
Dialogue offers and conditional narration
Each dialogue declares an offer — when it should play, and at what priority. Talk to a suspect before you find the evidence and you get one scene; talk to them after, and a more specific offer wins — no ordering to maintain, no scripting.
Within a scene, conditional narration lets you gate individual lines on state. A narration line whose condition fails is skipped; on a node with choices, only the line is hidden and the choices stay. A beat belongs only to a player who earned it, without fabricating fake choices. Choices can be gated too: shown greyed out with a reason when locked, or held back as a fallback for when nothing else is available.
Wren's offers: the confrontation gated on evidence, the first meeting as the fallback — the inspector shows which one wins right now.
A live session: the d20 roll, the effects it fired, where the story can go next, and every flag it touched.
Playtest in place — then hand anyone a playable file
Walk any scene with a live simulated game state: seeded, deterministic dice, a rewindable transcript, forced check outcomes, and edit-while-playing. When a scene is ready for feedback, export a share build — one self-contained HTML file that plays in any browser, no install.
Validation everywhere — on save, in CI, in your pipeline
Thirty families of checks run on every save and stream to every open editor window. The validator catches classic structural bugs like dangling references, unreachable nodes, quests that can't complete, and dialogue-offer mistakes. It also includes a prose check that learns your project's proper nouns to act as a narrative-aware spellchecker inline as you type.
The same validator runs headless as parlance ci-check, so a broken story fails the build before it ships. And Explore plays the story for you — every choice, both outcomes of every check — to find the nodes no playthrough reaches and the states where a player gets stuck.
$ parlance ci-check . --strict ✗ [REF] dlg_accuse: choice targets missing node "node_confession" ⚠ [OFFER] dlg_bragg_first: priority 1 but no 'when' — it out-ranks every other offer forever ⚠ [FLAG] flag "heard_bell" is set but never read exit 1 — the build fails, the story stays whole
A contract, not an exporter
Your engine reads the exact files the editor writes. The runtime semantics are a published contract with conformance vectors — ports prove themselves against the vectors, not against vibes.
The Godot runtime executes Parlance JSON natively in GDScript and is verified against the published conformance suite. The same vectors are how any engine — Unity, custom, whatever — gets a provably-correct port.
The contract, schemas, and vectors are published as parlance-spec under MIT — your data's meaning never depends on our goodwill.
There's also an MCP server, so LLM agents can read and write project data through the same validated path the editor uses.
PASS mulberry32 6 vectors PASS evaluate 53 vectors PASS applyEffect 29 vectors PASS resolveCheck 24 vectors PASS stepDialogue 24 vectors PASS chooseChoice 17 vectors PASS advanceNode 14 vectors PASS resolveCharacterDialogue 16 vectors PASS nextContinuations 4 vectors PASS resolveQuests 7 vectors PASS progression 13 vectors 207 passed, 0 failed, 0 skipped
Try it on a real mystery
The demo project is a complete, tiny whodunit: one night, one body, three suspects, three endings. Skill checks with real failure branches, evidence-gated dialogue offers, counters, quests — every feature demonstrated in a story you can actually play. Released CC0.