Building a solo RPG campaign engine

I’ve been building Elegy Campaign Player, a single-player campaign webapp for the Elegy 4th Edition tabletop RPG found at Elegy 4e. It’s a solo vampire game, and the digital version implements the full 124-page beta manual.

The engine

The core is 19 TypeScript modules covering character creation, combat, the oracle system, NPC interactions, and multi-night campaign progression. Everything is deterministic given a seed, which makes testing straightforward - 886 tests across 48 files.

Optional LLM narration

The interesting twist is optional LLM-powered narration via OpenRouter and portrait generation via Gemini. The game is fully playable without AI - the oracle and narrative systems work on their own. But when enabled, the LLM adds atmospheric descriptions and the portrait generator creates character art from the game state.

This was a deliberate design choice. The AI enhances the experience but never gates it. If the API is down or you just prefer pure mechanics, the game works exactly the same.

What I learned

The biggest lesson was in scope management. A 124-page manual is a lot of rules to encode. Breaking it into isolated modules with clear interfaces made it tractable. Each module owns its domain and exposes a clean API to the campaign orchestrator.