Made local LLMs tell a coherent story: a thesis platform that turns books into playable text adventures.
M.Des thesis at OCAD University: four prototypes and seven benchmarked models, shipped as a locally hosted web app inside a custom-built arcade cabinet.
- Designer, Researcher & Developer · 2024–2025
- AI/ML
- Interaction Design
- Fabrication

- 4
- Prototypes built and tested, terminal to web app
- 7
- LLMs benchmarked, from 600MB to 20GB
- 2
- Play modes: structure and freedom as a player choice
- DFX '25
- Exhibited in a custom CNC-machined arcade cabinet
The problem
Large language models can generate engaging text turn by turn, but they have no mechanism for staying faithful to an existing story. Without constraints, they lose the thread of source material within a few exchanges: narrative deviations accumulate, characters behave inconsistently, and the original plot disappears entirely.
The design question was not whether AI could generate story content (it clearly could) but whether it could be structured to stay faithful to an existing narrative while still responding meaningfully to player choices. One early playtest had the mutineers and loyalists swap roles entirely. Another turned a historic naval conflict into a dispute over who stole the breadfruit.
Prototype 1: the core problem, revealed in a terminal
The first prototype ran entirely in a terminal. Using Python, Ollama, and llama2, I built a simple game loop where a system prompt instructed the model to act as a text-adventure narrator following the story of the mutiny on the HMS Bounty. The player selected numbered options each turn and the model advanced the narrative.
Testing revealed the core problem immediately. The model handled individual turns well, but after five or six exchanges it began to contradict itself, lose track of plot details, and generate content with no relationship to the source material. It was generating plausible text, not telling a specific story.
Prototype 2: inventing the Story Card
The failure of Prototype 1 made one thing clear: the model needed a persistent reference it could check against at each turn. Drawing on Rob Śliwa's work with local LLMs and his use of player and companion cards to anchor narrative behavior, I developed the Story Card: a pre-written YAML summary of the Bounty narrative covering the mission, the tension between Bligh and Fletcher Christian, the mutiny, Bligh's 3,600-nautical-mile open-boat voyage to Timor, and the fate of the mutineers.
At each turn the model checked its response against this summary before generating output. Major plot deviations dropped substantially, though the model still occasionally ignored the Story Card when it could generate more interesting content without it.
“The tension between structure and freedom in AI storytelling is not a problem to solve but a parameter to tune.”
Prototype 3: benchmarking seven models
Before building Prototype 3, I ran structured benchmarking across seven models ranging from 600MB to 20GB, including GPT-4-Turbo, llama2, llama3, Phi-2, Mistral, and Gemma. Larger models did not perform better: GPT-4-Turbo was prone to overgeneration, while smaller models like Phi-2 drifted from the narrative frequently. The 7-to-10-billion-parameter range, specifically llama3 8B, produced the most consistent Story Card adherence with reasonable response times. I also lowered the model temperature from 0.6 to 0.2 after observing that higher settings consistently weakened adherence.
The terminal was replaced with a Pygame GUI designed to feel like a typewriter. I presented Prototype 3 at OCAD's notQuiteThere(yet) exhibition in October 2024. Engagement increased substantially, but the interface still felt like a prototype wrapper, not a platform.
Prototype 4: web stack, two play modes, and a cabinet
For the final prototype I rebuilt the architecture entirely: FastAPI backend, Vite and React frontend, both new to me going into this project. Two insights from watching players drove the interface redesign. First, long horizontal text streams were hard to read, so I moved to a two-column layout with narrative on the left and controls on the right. Second, free text input created confusion when the model was already offering numbered choices, so I replaced the text box with numbered buttons.
The redesign also introduced Story Mode (temperature 0.2, closely aligned with the Story Card) and Forge Mode (temperature 0.8, significantly more latitude for unexpected branching), making temperature an explicit, player-controlled design variable. At the DFX exhibition, Forge Mode became the dominant choice, and players gathered to watch sessions unfold.


The final build
A locally hosted React and FastAPI web application with a custom Ollama backend running llama3 8B. A Story Card system providing a persistent YAML narrative reference at every model turn. Two play modes giving the player direct control over the structure-to-freedom ratio. A two-column interface with scrollable narrative text on the left and numbered button input on the right, housed inside a custom CNC-machined arcade cabinet built from half-inch MDF with painted panels and vinyl decals, enclosing a 27-inch monitor with the backend running inside the enclosure.


Reflection
The most important design decision in this project was not a UI choice: it was the invention of the Story Card. Every other improvement, from temperature tuning to model selection to the mode system, was built on top of that one structural idea: give the model a persistent reference it checks at every turn, and narrative coherence becomes manageable.
Story Mode and Forge Mode did not resolve the tension between structure and freedom. They made it explicit and gave the player control over where on that spectrum they wanted to be. What I would push next: multi-book support with a Story Card authoring interface, cloud model options for faster response times, and a multiplayer mode where two players navigate branching decisions together.