Skip to content

5000Stadia/construct

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

196 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Construct Projector

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.

License: MIT Python 3.11+ Tests Substrate Status


The research question

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
Loading

The design bet: structural absence over instruction

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.


Architectural contributions

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.

Evaluation methodology

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 /feedback channel, 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).

Development methodology

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.


Proven in live play

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.


Quick start

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 Yard

Type 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/tests

Play 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.


Documents

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.

For technical reviewers: this README → ARC-LAYERCONCLUSION-AND-OUTCOMEENTITY-AUTHORITYOPTIMAL-IF-EXPERIENCE → the eval suite.


Engineering proof

  • 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).

Capability status

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

Family

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.

Project status

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.

License

MIT — see LICENSE. Built by @5000Stadia.


The model narrates. The world remembers, refuses, and keeps its own truth.

About

Construct Projector — an interactive-fiction engine that loads a stored world into a played, remembered holonovel. Built on pattern-buffer; the world you put a thing down in still has it when you return.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages