An interactive-fiction engine where the world's truth is a database and the model is only a voice. (“The Construct” for short.)
Step into a book, or a world built from one conversation. Put something in a drawer, wander for an hour, come back — it's still there. The world remembers, so the model doesn't have to.
Interactive fiction has always had to pick a failure. Hand-authored worlds are rich but rigid — every path pre-written. LLM-generated worlds are free but amnesiac — they contradict themselves within twenty turns, invent doors that were never there, and forget the spoon you set down. The failure isn't a model-quality problem; it's an architecture problem: the same context window is being asked to be the world's memory, its referee, and its voice.
The Construct is a working answer to: what does long-form generative fiction look like when those jobs are separated?
- pattern-buffer holds the world's truth — an append-only assertion log with object permanence, per-character knowledge frames, event causality, and as-of queries. Nothing is forgotten; nothing is invented over canon.
- The Construct turns that truth into a played experience — a host that classifies the player's move, adjudicates it against the map, advances a hidden story arc, composes a grounded briefing, and only then lets a model narrate. The model never holds state; it renders it.
The name is the metaphor: like the Construct in The Matrix, it's the runtime that loads any stored world into a lived one. pattern-buffer holds the pattern → the Construct loads it into a played → holonovel.
flowchart LR
P((Player)) --> C[classify]
C --> A[adjudicate<br/>map-governs]
A --> W[(pattern-buffer<br/>canon + frames)]
W --> K[clocks · beats ·<br/>hidden arc]
K --> B[grounded briefing<br/>truth only, spoilers absent]
B --> N[narrate<br/>the only expensive call]
N --> E[extract → Entity Authority<br/>resolve → commit]
E --> W
M[the Remembrancer<br/>NPC engines · world tick] -.cheap, parallel.-> B
Every hard problem in this genre — spoilers, secret-leaking, railroading, contradiction — is conventionally attacked with prompt rules ("don't reveal the killer"). Rules erode under pressure. The Construct's recurring move is to make the failure impossible to express rather than forbidden:
- Characters can't leak secrets because the secrets were never in their context window — each NPC decides its beat from its own
knows:frame, nothing more. - The narrator can't spoil the arc because the hidden
plot:frame is never in its briefing. - The story can't puppet your character because your character is never handed to it as a scene entity.
- Prose can't mint phantom places because free-text extraction passes through pattern-buffer's single resolve seam, which cannot type-slip — bind to a known entity, mint once with the right kind, or drop; Entity Authority adds the channel permissions on top (who may mint what).
Where a rule would have been added, a doorway was narrowed instead. The design docs record each of these as a named decision with the live failure that forced it.
The substrate (permanence, frames, time) is pattern-buffer's. What the Construct contributes is the layer nobody had: the drama engine over a truth store.
| The hidden arc layer | A story's destination authored into a private plot: frame the player never sees, navigated by beats, clocks, and a pacing ladder with anti-railroading guards. The arc pushes the world at you; it structurally cannot move you. |
| Conclusion-as-effect | No win/loss verdict is ever computed and announced. A story ends on its own decisive event ("IT"), and the ending's character — triumphant, costly, bittersweet, quietly failed — is derived from which of the story's load-bearing causes the player actually established. Turns never force a close: a detective can study one clue for three hundred turns. |
| Entity Authority | The channel-permission policy over pattern-buffer's resolve seam: every free-text canon write binds-before-minting against a canon roster, with channel-scoped mint permissions (player input cannot conjure people; prose cannot conjure places) and ambiguity never minting. The misshapen entity graph becomes impossible to create instead of cleaned up after. |
| World laws | Every generated world is authored ON a constitution: 1–4 named, universe-governing dynamics (rule · cost · embodiment · texture), register-gated so a courtroom drama can never draw "the Force," anti-pastiche-judged, committed as queryable canon with embodiment links. Laws the character inherently understands ground the opening; discovered laws bind silently until play uncovers them. |
| First-mention permanence | A proper-named detail the world establishes ("The Hart and Bell") commits immediately as a minimal, non-present stub — engagement paints the rest. The gate's evidence is real casing recovered from prose, fail-closed; generic descriptions ("the street") still never mint. |
| The Remembrancer | The protagonist's own memory as a silent turn participant, symmetric with NPC engines: a screened knowledge-frame digest, contributing only felt interiority. It owns self-questions mechanically, and it powers player-authored retconning — "I remember my childhood friend John Johnson" commits real autobiography through a guarded channel where world-claims become beliefs that can never satisfy the mystery, and contradictions quarantine in favor of the first established truth. |
| Knowledge frames as gameplay | Interviewing a witness is mechanically real: authored clues sit in their frame (pattern-buffer's knows: frames), gated by Construct's reveal conditions, and surface into yours only when your questioning earns them — which is what advances the case. A diegetic notebook renders your frame back to you as the case-board. |
| Deterministic resolution deck | Uncertain actions draw from a pre-rolled, seeded 100-tier outcome bag (fail-forward: every failure opens something) — drama without a per-check model call and fully replayable. |
| Death as staged permanence | A per-chapter death_policy decides whether death ends the story (action/adventure), is transformed by the premise (time loops, ghosts), or is capped by genre convention (cozy mystery → wounds, capture, ruin). Mortal peril must be staged — the world warns before it kills — and a death ends in a testament epilogue: the world after you, and your effect on it. No respawn, no next chapter. |
| Episodic continuation with settled history | A concluded story offers the next chapter over the same evolved world: consequences of your ending ride forward as canon events with causal receipts, answered questions become closed history that is never re-opened as mystery, and personal promises are extracted as first-class fuel the next chapter must honor or consciously pay off. |
| Diegetic time as the only clock | Turns are free; only in-world time can pressure a story, and only when a deadline genuinely belongs to it (the bomb, the King's dinner). Numeric stakes (oxygen, fuel) are gauges folded from signed per-turn deltas — surfaced as mounting pressure, never a HUD. |
| A living world | Off-screen characters move on their own schedule (committed through the same gated doorway, discovered rather than narrated), companions interject unprompted, and presence holds — a character who is here stays engageable rather than evaporating between turns. |
The claim of a system like this can't be proven by unit tests alone — the product is a felt experience over hundreds of turns. The project's evaluation stack, all in-repo and reproducible:
- A structured live-eval suite — 5 scenarios × 18-turn schedules (follow-the-thread / push-the-edges / draw-on-character-knowledge / conclude) driven by an LLM player, with per-scenario assessments and a consolidated engineering report:
docs/design/eval/. - An adversarial critic campaign — player-agents primed to break immersion and file their own bug reports through the in-game
/feedbackchannel, including deliberate off-path runs (pursuing a romance the story never offered) and cross-chapter continuations. Every filing was independently triaged against engine ground truth before anything was "fixed":eval/09-critic-campaign.md. - A five-probe live acceptance set — object permanence, loop closure, frame non-leak, player agency, honest adjudication — passed 5/5 in live play and re-verified as the engine grew.
- A generalized synthesis — the campaign's findings distilled into five portable pillars of the optimal interactive-fiction experience (truth-keeping, the player's story is the story, proportion, initiative, the ending is the payoff):
docs/design/OPTIMAL-IF-EXPERIENCE.md. - 800+ test functions across 36 files — including structural pins for every invariant the design docs promise (frame non-leak, protected-key concealment, mint-channel discipline, terminal precedence, no-reopen of settled history).
The engine was built through a multi-agent adversarial review loop: every substantive design goes to an independent reviewer model as a written spec letter before implementation, and every build goes back as a diffable report reviewed against the real worktree — with explicit BLOCKED / YELLOW / GREEN verdicts. The full correspondence (440+ numbered letters) is the project's decision record; blockers the reviewer caught on this codebase include a frame-privacy leak in a resolver roster, a policy gate that mis-fired on first contact, and an event-causality write that silently landed on the wrong row. Nothing ships on self-review.
The shipped example, The Rain in Bluegate Yard — a complete original Victorian murder mystery (London, 1888; a dock messenger dead in Bluegate Yard; a plain-clothes bureau racing the Met) — plays end-to-end on a real model: grounded cold open, earned clue trail, companion texture, a staged conclusion scene, a consequence-bearing epilogue, and a next chapter grown from the wake of the first. Three further worlds (a dark-fantasy pilgrimage, an undersea survival thriller, a country-house death) exercise the other genre shapes.
Worlds are built, not hand-coded: drop any prose document in and it becomes a playable world, or build one live from a one-line brief through the session-zero interview.
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e .
construct start # guided menu: pick a world, make a character, play
construct play bodycase # or jump straight into The Rain in Bluegate YardType what you do, line after line. Every turn is saved; bare construct play resumes. --debug shows each turn's receipts — every write the turn committed, and why.
construct import path/to/your-story.md # any .txt/.md becomes a playable world
construct new --interview "a drowned harbor town with a harbor-master's secret"
construct turn bodycase "I look around." --debug # one-shot form for scripting/testsPlay from your phone: Telegram (construct setup telegram, then construct telegram) or Discord (docs/DISCORD.md) — both outbound-only transports (no port, no tunnel), thin clients over the same session API:
from construct import Session
s = Session.open("bodycase", player_id="me")
print(s.turn("I look around.").prose)
s.close()Bring any LLM behind the provider interface; ships with a zero-marginal-cost ChatGPT-subscription default.
The project is design-first: 60 design documents, each recording a decision, the live failure that motivated it, and the review verdict it shipped under.
- docs/CONCEPT.md — the founding brief: vision, host architecture, the arc layer.
- docs/design/00-INDEX.md — the curated map of all design docs, by layer.
- docs/design/OPTIMAL-IF-EXPERIENCE.md — the research synthesis: five pillars of the optimal interactive-fiction experience, grounded in the evaluation corpus.
- docs/design/eval/ — the evaluation suite: consolidated report, per-scenario assessments, the critic campaign.
- docs/LEXICON.md — the working vocabulary.
For technical reviewers: this README → ARC-LAYER → CONCLUSION-AND-OUTCOME → ENTITY-AUTHORITY → OPTIMAL-IF-EXPERIENCE → the eval suite.
- 800+ test functions, 36 files, zero live model calls in the suite — engine extraction via pattern-buffer's
StubModel, host cohorts via a canned provider; the full suite runs in under two minutes. - Deterministic spine, model calls only at the boundaries. Classification, adjudication, arc evaluation, entity resolution, and all bookkeeping are deterministic or cheap-tier; the expensive model renders prose and voices characters, nothing else. Turn latency is protected by a deferred-settle design: post-narration bookkeeping overlaps the player reading.
- Fail-open discipline everywhere it must be. No enrichment call may sink a turn; the climax cannot be lost to a provider hiccup; every dropped cohort is receipted in the turn trace.
- Receipts-first debugging. Every turn emits a structured trace — writes, resolver decisions with reasons, clocks fired, clues surfaced, cohort calls — the same record the debug CLI, the tests, and the eval reports all read.
- Honest failure records. The eval reports and design docs record what broke and what it cost, by name, next to what shipped — including a full fresh-eyes architecture audit (AUDIT-2026-07-FRESH-EYES).
| Surface | Status | Notes |
|---|---|---|
| Turn loop (classify → adjudicate → arc → narrate → commit) | Live | Deterministic spine; model at the boundaries only |
| World ingestion (document → playable world) | Live | Build narrated in plain stages; identity-coherence gate at build |
| Session-zero interview + character creation (the Foyer) | Live | Play-as-anyone; name/pronouns/background authoritative over authored defaults |
| Hidden arc: beats, clocks, pacing, convergence | Live | Anti-railroading guards; refusal handled diegetically |
| Interview/examine clue delivery + case-board notebook | Live | Topic-aware; earned-only; the notebook is the player's own frame |
| Conclusion-as-effect + epilogue + episodic continuation | Live | Settled history never re-opens; consequences carry causal receipts |
| Death & the testament (per-chapter policy) | Live | Staged peril; premise-transformed death for loop/ghost shapes |
| The Remembrancer + player-authored memory (retcon) | Live | Contradictions quarantine; world-claims become beliefs |
| Entity Authority + first-mention permanence | Live | Channel-scoped minting; prose-casing evidence, fail-closed |
| Gauges, diegetic time, world-tick, companions | Live | — |
| World laws (authored constitution, register-gated, disclosure axis) | Live | The narrator briefs it every turn on a reserved lane; adjudication enforces it |
| Scene imagery (per-location AI illustration) | Live | Oil-painting style; regenerates only when the scene truly changes |
| Telegram / Discord / CLI / REPL transports | Live | One session API; outbound-only, no inbound exposure |
| Multi-player shared worlds | Designed, not built | Design notes — shared-world observer semantics to be worked jointly with the substrate |
| Narrator-authored NPC movement (the narration seam) | Specified, gated | The highest-leverage known gap; named in the synthesis doc |
Three projects, one line of research — each a résumé of the last:
- pattern-buffer — the append-only world-state engine: current state, knowledge frames, and history as derived projections over one assertion log. The Construct is its first full-depth adopter.
- Kernos — a personal-agent kernel (v1.0, research complete). The Construct inherits its cohort architecture — bounded specialist workers around one principal voice — and its house methodology: design-first, spec-reviewed, receipts-first.
- The Construct (this repo) — the drama engine: what a story is, mechanically, when the world underneath it is guaranteed to hold.
Pre-1.0, research active. The engine plays end-to-end on a real model; the current suite is green (800+ tests); the evaluation corpus and design record are current through July 2026. The remaining named gaps are documented as future work in the synthesis and the capability table, not left implied.
MIT — see LICENSE. Built by @5000Stadia.
The model narrates. The world remembers, refuses, and keeps its own truth.