The engine contract

Most narrative tools connect to engines through an exporter: authoring format in, engine format out, and a translation layer in between that must be kept honest by hand. Parlance replaces the exporter with a contract.

No export step

A shipping game loads data/ — the same per-entity JSON files the editor writes — and nothing else. There is no bake, no conversion, no moment where the authored truth and the shipped truth can diverge. (Route and snapshot fixtures live in tests/ beside it precisely so the game never reads them.)

For this to be safe, "what the data means when executed" can't live in one implementation's head. So it's published in two layers:

  1. The runtime contract — a document defining the execution semantics precisely: how conditions evaluate, how effects apply, how checks roll (d20 + skill ≥ difficulty on a seeded mulberry32 RNG), how offers resolve, how quest resolution fires effects to a fixpoint, what happens on every edge case (unknown ids, unadvanced quests, cycles) — the boring cases spelled out, because the boring cases are where ports drift.
  2. Conformance vectors — machine-readable test cases for each runtime function: given this state and this input, exactly this output. A port doesn't argue it's correct; it passes.

Both layers, with the schemas and the reference validator, are MIT-licensed — deliberately more open than the tool itself, so your data's meaning never depends on our goodwill.

Ports prove themselves

The TypeScript runtime — published on npm as @orbitope/parlance-runtime from v0.16.0, MIT — powers the editor's own playtest, which means every scene you play in-editor is exercising the same contract your engine implements. The public Godot/GDScript runtime ships its conformance scoreboard in the README:

PASS  evaluate                    53 vectors
PASS  applyEffect                 29 vectors
PASS  resolveCheck                24 vectors
PASS  stepDialogue                24 vectors
PASS  resolveCharacterDialogue    16 vectors
PASS  nextContinuations            4 vectors
PASS  resolveQuests                7 vectors
PASS  progression                 13 vectors
...
207 passed, 0 failed, 0 skipped (not yet ported)

Every family passes. A port that is not there yet reports each unported function as SKIP, declared rather than fudged — this one did, until quest resolution and progression landed. A Unity/C# port, a Rust port, a bespoke-engine port all follow the same path — implement the contract, run the vectors, ship when green. The integration guide covers the practical steps.

The division of labor

The contract is also explicit about what the host engine owns: playing cutscene assets, running quest resolution after state transitions, persistence, presentation. Parlance defines narrative meaning; your engine owns everything it's better at. The boundary is documented per-function, so "whose bug is this?" has an answer.

What this buys you

Next: engine integrations · the open spec · schema-first data