splinter-keep — it calls itself “The Chaos” in-game — is a terminal RPG where an LLM runs the whole game: it narrates the scene, offers you choices, resolves whatever you type back, and rolls dice behind the scenes against a genuinely simple d6-based rules system. Every turn gets appended to a running story book, so by the time a campaign ends you’re left with something that actually reads like a book rather than a chat log.
The whole game loop lives in one terminal app — there’s no separate “DM” service and “player” client, just a TUI that calls the LLM directly for every scene and every outcome. The interesting constraint was making that work with a local model running on my own GPU instead of a hosted API. I went through a lot of different local models while building this, and every single one had its own quirks and failure modes: refusing to follow the output format, inventing rules, forgetting inventory, that sort of thing.
It only became reliably playable once I added real guardrails: a strict structured output format the LLM has to fill in every turn — choices, log line, state changes, as a JSON block — and a second, separate LLM call whose only job is to check whether the player’s action is even valid given the current character and world state, before the main narrative call runs at all. That second-opinion step mattered more than any single prompt tweak.

Even with all that, I’ll be honest: the actual writing quality of a small local model is nowhere near what you get from pointing the same code at a larger hosted model instead — the game supports both, swappable in config, and the difference in prose is obvious. But getting a local model to behave at all, reliably, turn after turn, was most of the fun here. Still a great experience playing around with LLMs either way.
Full architecture notes, the rules system, and the code for both the guardrails and the LLM strategies are in the splinter-keep repository.





