ChronicleEngine: The Chronicler’s Ledger

Deterministic state for infinite stories, and why your AI dungeon master needs a constitution


In 2024, I watched a friend lose a six-month D&D campaign to a language model’s memory.

He’d been using an AI assistant as a solo game master—feeding it session summaries, asking it to generate encounters, letting it narrate his character’s journey through a homebrew world. It worked beautifully for months. The AI remembered his character’s grudge against the merchant guild, the cursed sword he’d found in the tomb of the Lich King, the NPC companion who’d sacrificed herself to save him.

Then, around session forty, the context window filled up. The AI started forgetting. Small things at first—the companion’s name, the sword’s specific curse. Then larger things. By session fifty, the AI had contradicted three major plot points, resurrected two dead characters, and placed his party in a city that had been destroyed twenty sessions earlier.

Six months of story. Gone. Not deleted—worse. Corrupted by hallucination.

I knew there had to be a better way.


The Memory Problem

Here’s the uncomfortable truth about using language models for long-running narratives: LLMs don’t remember. They predict.

When you ask ChatGPT about something from earlier in the conversation, it’s not retrieving a memory. It’s predicting what a helpful assistant would say given the tokens in its context window. Most of the time, this prediction aligns with what actually happened. Sometimes it doesn’t.

For short conversations, this works fine. For a forty-session campaign? It’s a time bomb.

The failure modes are predictable:

Context overflow. The model’s window fills up. Old information gets summarized or dropped. Details that seemed unimportant at the time—but become crucial later—disappear.

Soft contradictions. The model generates content that almost matches previous events but subtly differs. The magic sword was cursed to drain life—or was it cursed to compel violence? The model isn’t sure, so it picks one. Sometimes it picks wrong.

Confident fabrication. Asked about something it’s forgotten, the model doesn’t say “I don’t know.” It generates a plausible-sounding answer with full confidence. The player has no way to distinguish memory from fabrication.

Accumulated drift. Each small inconsistency compounds. Over dozens of sessions, the narrative world becomes incoherent—not through any single catastrophic failure, but through the slow accumulation of probabilistic errors.

This isn’t a bug in language models. It’s their nature. They’re prediction engines, not databases. Asking them to maintain perfect consistency across thousands of interactions is asking them to be something they’re not.


The Event-Sourced Solution

ChronicleEngine takes a different approach. Instead of trusting the AI to remember, we make the system remember for it.

The core insight is borrowed from distributed systems: event sourcing. Instead of storing the current state of the world (“the player has 47 gold”), we store the sequence of events that produced that state (“the player found 50 gold, spent 3 gold on rations”). The current state is always derived from the event log—never stored independently, never trusted to memory.

This has profound implications for narrative AI:

The event log is the source of truth. Not the AI’s context window. Not a summary. Not a character sheet. The complete, immutable sequence of everything that happened.

The AI generates content, not truth. When ChronicleEngine needs a room description or an encounter, it asks the AI to generate creative content. But that content is immediately validated against the rules engine and recorded as events. The AI proposes; the system disposes.

Prose derives from events, never contradicts them. When we generate narrative prose, we’re transforming event data into readable text. If the event log says “attack missed,” the prose cannot say “the blade struck true.” The Chronicler—our narrative generation layer—is bound by the Referee’s truth.

Any session can be perfectly reconstructed. Given the event log, we can replay the entire campaign. Same inputs, same outputs, same story. This isn’t just useful for debugging—it’s the foundation of narrative integrity.

This is SwiftVector applied to storytelling: deterministic control around stochastic creativity.


The Three Pillars

ChronicleEngine separates concerns into three distinct layers, each with clear authority:

The Referee (Rules Engine)

The Referee is the arbiter of truth. It processes player actions deterministically, enforcing game mechanics without creativity or interpretation.

func process(state: GameState, action: PlayerAction) -> (GameState, [GameEvent])

This is a pure function. No randomness inside the engine itself—random values are passed in as parameters. No I/O. No network calls. Same inputs always produce same outputs.

The Referee doesn’t know about goblins or magic swords or ancient curses. It knows about entities with hit points, damage calculations, and state transitions. It emits events: attackRolled, damageDealt, entityDied. These events are the atomic units of truth.

Why this matters: When the narrative says a character died, it’s because the Referee emitted a characterDied event. Not because the AI decided it would be dramatic. The death is earned through game mechanics, recorded in the event log, and permanent.

The Creator (Content Generation)

The Creator provides content when the Referee needs it. “The player entered a new room—what’s in it?” “Combat started—what does the enemy do?”

This is where AI creativity lives. The Creator can be:

  • RandomTableGM: Static lookup tables. Fast, free, deterministic if seeded.
  • AIGameMaster: Claude API calls. Dynamic, creative, requires network.
  • ModuleGM: Authored scenarios. Community content with curated quality.
  • HybridGM: Edge AI for common patterns, cloud AI for novel situations.

The crucial boundary: The Creator proposes content. The Referee validates it. If the AI suggests an encounter with a dragon in a 10x10 room, the Referee can reject it. If the AI generates treasure that breaks game balance, the Referee can constrain it.

The Creator is swappable. You can play the same dungeon with random tables, AI generation, or hand-authored content. The Referee doesn’t care. The event log doesn’t care. The architecture enforces the separation.

The Chronicler (Narrative Engine)

The Chronicler transforms events into prose. It reads the event log—the ground truth—and generates readable narrative.

[roomEntered: "Dusty Corridor"]
[torchLit: remaining=5]
[enemySpotted: "Goblin Warrior"]
[attackRolled: hit=true, roll=17, target=13]
[damageDealt: amount=6, target="Goblin"]
[entityDied: "Goblin Warrior"]

Becomes:

Alaric stepped into the dusty corridor, torch flame dancing against ancient stones. A goblin lunged from the shadows—but Alaric was faster. His blade flashed once, and the creature crumpled.

The Chronicler has creative freedom in how it describes events. It cannot change what happened. The attack hit because hit=true in the event log. The goblin died because entityDied was recorded. The prose must honor these facts.

This is narrative truth: the story matches the game because both derive from the same source.


Prompting Imagines. Simulation Discovers.

There’s a deeper philosophy here that extends beyond technical architecture.

When writers use pure LLM prompting for creative work, they get:

  • Infinite possibilities (overwhelming)
  • No constraints (decision paralysis)
  • Hallucinated continuity (inconsistent)

The blank page problem, amplified by AI. “Write me a story” produces generic output. “Write me a story about a warrior” produces slightly less generic output. The AI will generate something, but it won’t generate discovery.

ChronicleEngine inverts this. Instead of prompting for stories, you simulate worlds. Instead of asking “what happens next?”, you take actions and observe consequences.

  • Bounded randomness (meaningful surprise)
  • Rule-enforced consequences (earned drama)
  • Event-sourced truth (perfect memory)

The difference is profound. When you prompt “the hero fights a dragon,” the AI generates a fight scene based on tropes and training data. When you simulate a fight—rolling attacks, tracking hit points, applying rules—you discover whether the hero wins or dies. The outcome is earned, not generated.

This is why ChronicleEngine produces stories worth keeping. Not because the prose is better than ChatGPT (it might not be), but because the events are real within the game’s logic. The character who survives the dungeon earned their survival through player decisions and dice rolls. The tragedy that unfolds wasn’t scripted—it emerged from simulation.

Prompting imagines. Simulation discovers.


Multi-Agent Architecture

ChronicleEngine isn’t just a game engine with AI features. It’s a multi-agent system where autonomous entities coordinate through shared state.

PlayerAgent: Receives commands from the human (or, in Writer Mode, from an AI pursuing goals). Emits PlayerAction events.

GMAgent: Generates content in response to game state. Different implementations (random tables, Claude API, authored modules) share the same protocol.

NPCAgents: In Milestone 2+, NPCs act autonomously. A goblin evaluates its hit points, sees the player’s strength, and decides to flee. This decision is made by a behavior tree or LLM—but the action goes through the Referee like any other.

ChroniclerAgent: Watches the event stream and generates prose asynchronously. Doesn’t block gameplay; doesn’t influence outcomes.

All agents communicate through the event log. No agent can directly modify another’s state. No agent can bypass the Referee’s authority. The architecture enforces isolation.

This is The Agency Paradox in miniature: multiple AI agents, each with genuine capability, operating within boundaries that preserve human authority and system integrity.


Why Swift?

ChronicleEngine is built in Swift for the same reasons as ClawLaw and Flightworks: when control is the concern, use a language built for control.

But there’s an additional reason specific to narrative applications: edge AI enables private, offline storytelling.

Your stories are personal. Your characters, your choices, your failures and triumphs. ChronicleEngine keeps them on your device by default:

Privacy by architecture. The event log never leaves your device unless you explicitly share it. No cloud database tracking your narrative choices.

Offline capability. With edge AI and local content, you can play without internet. The hybrid architecture uses cloud AI for novel situations while handling common patterns locally.

Responsive gameplay. Local inference means no network latency for routine interactions. The game feels immediate because it runs on your hardware.

Swift’s performance characteristics—compiled binaries, efficient memory management, native Apple Silicon support—make this practical. A narrative engine that ran purely in Python would struggle with the real-time requirements of gameplay.


The Three Modes

ChronicleEngine serves three distinct user types through a single unified architecture:

Player Mode: Solo gamers who want tactical RPG adventures with AI game mastering. They value meaningful choices, strategic combat, resource management, and emergent stories.

Creator Mode: Module authors who build bounded content for others to play. They define rooms, encounters, and narrative constraints. The AI improvises within their authored boundaries.

Writer Mode: Fiction writers who use simulation as a discovery tool. They set up scenarios, let AI play through them, and extract narrative raw material. The game becomes a plot generator.

The same engine serves all three. The same event log format. The same Referee enforcing rules. The same Chronicler generating prose. Different interfaces, same foundation.


What ChronicleEngine Proves

Every reference implementation in the SwiftVector family demonstrates the core thesis in a different domain:

  • ClawLaw proves it for desktop agents (containment, budget, authorization)
  • Flightworks proves it for safety-critical systems (aviation, real-time, certification)
  • ChronicleEngine proves it for creative applications (narrative, long-running, emergent)

ChronicleEngine is perhaps the most surprising application. Storytelling seems like the last place you’d want rigid determinism. Isn’t creativity about freedom? Isn’t narrative about surprise?

Yes—but sustainable creativity requires structural integrity.

The most creative improvisational theater operates within constraints. The most surprising plot twists honor the story’s internal logic. The most memorable game sessions feel earned because the rules were consistent.

ChronicleEngine doesn’t constrain creativity. It provides the foundation that makes long-running creativity possible. The AI can be as wild as it wants in generating content. The Referee keeps it honest. The event log remembers what actually happened. The Chronicler tells the truth about it.

A rules-bound world that remembers what happened and tells the truth about it.

That’s not a limitation on storytelling. That’s the foundation of stories worth keeping.


ChronicleEngine is open source under CC BY-NC-SA 4.0. The core framework (ChronicleEngineCore) provides protocols and patterns; Chronicle Quest is the reference RPG implementation.

If you’re building narrative applications—interactive fiction, visual novels, AI-assisted writing tools—and you’ve struggled with context limits, hallucinated continuity, or stories that drift into incoherence, this architecture might help.

Reach me at stephen@agentincommand.ai or explore the code on GitHub.


"Prompting imagines. Simulation discovers."