Back to Projects

Project

Work in progress

Tome & Quill

A D&D character builder, campaign platform, and procedural world engine with a virtual tabletop. Recent v1 work connects DM and player hubs, story-bible reveals, tactical maps, and a reproducible local test stack.

Next.jsTypeScriptPostgreSQLDrizzle ORMPlaywrightProcedural GenerationSVGThree.js
Tome & Quill

Overview

This started as a D&D 5e character creator for the 2014 rules, with a 2024 edition preview, guided level ups, multiclassing, character branching, and PDF export.

Then it grew. The question that changed the project was simple: if I can generate a character, why can I not generate the world they came from? Tome & Quill is now a homebrew world engine, and the character creator is one surface on top of it.

The goal is a single living world a DM can grow for a thousand in-world years, where the map, the history, the peoples, and the campaigns played inside it are one connected graph rather than five disconnected tools.

A campaign around the world

The recent v1 work brings campaign invitations, player onboarding, DM character review, session scheduling, reminders, recaps, and journals into that world. The DM hub supports preparation and control; the player hub collects the next session, revealed lore, known people and places, and the player's own character.

The tactical layer includes grid maps, tokens, initiative, HP, conditions, line of sight, fog of war, and explored memory. A DM can preview what a player will see. The story bible connects NPCs, factions, items, quests, and events to places and eras, with per-player reveals.

Three axes and one graph

Everything in the world is an entity positioned on three axes, and almost every feature turns out to be "put a new entity type on those axes."

  • Space. A node tree running world to region to settlement to interior to battlemap. Anything can be anchored to a node, and optionally to a coordinate inside it.
  • Time. A deterministic change log. World state is a seed plus an ordered list of operations, and named eras are just bookmarks over that list. Anything can carry a time anchor, so the whole world can be replayed as of any moment.
  • Knowledge. Visibility and scope. The DM decides who knows what and when. This is fog of war over information as well as over terrain.

The map is the spatial view of that graph, the timeline is the temporal view, and each player's hub is the knowledge-filtered view.

Zooming

The ask was "Google Maps for a fantasy world," which sounds like one infinite coordinate space with a tile pyramid. That approach is a trap for a procedural world, because every scale has to be generated coherently and kept in sync with every other scale, on demand, in a browser.

Instead the map is a set of nested documents. The world map is one document. A settlement opens into its own document with its own coordinate space and its own generator, and the transition animation sells the continuity. Only one document is ever rendered, so the browser never holds the continent and every town and every building at once. Infinite detail becomes a question of how deep the DM has bothered to author, not a rendering load.

Procedural history

Generated history is a prefix on the same change log the app already replays. The freshly generated world sits at position zero as the ancient world, and history is written as operations in front of it: towns founded and razed, states annexed, dynasties renaming what they conquered, wonders raised and lost.

That has a nice consequence. The features that make the past visible already existed, because they were built for the present. Rename operations replayed through the log produce "previously known as" for free. The era scrubber already knew how to walk a list of operations, so it now walks the ancient world too.

History is authored by weighted programs with causal constraints, not simulated agents. No model is called anywhere in it. Believability comes from the constraints and the context, and the whole thing is reproducible from a seed.

Inhabitants

A party walks into any building and finds someone there. The same innkeeper is behind the bar next month. None of it is stored until it matters.

Population is a deterministic read model per settlement, so who lives where is derived rather than persisted. An inhabitant is only written to the database when the DM touches them, at which point they become a durable entity that survives unrelated edits to the world around them. The same demographics feed world-aware character creation, so a player can roll a character who plausibly comes from the place they are about to play in.

Status

The v1 finishing pass merged in October 2026. It includes the campaign flows, generated history, settlement and interior maps, tactical battles, and expanded story bible. Atlas and Cyanotype themes and improved character and map exports are part of the same pass. Version 1.0 is in release preparation; a published release hasn't been verified.

The local stack now includes PostgreSQL, demo data seeded through real route handlers, and headless sign-in. Browser fixtures cover roles in both themes and at different viewport sizes. Authorization tests cover anonymous requests, nonmembers, and wrong owners. Player payloads exclude the original generation seed, the world operation log, and private DM information.

Performance work focused on smaller initial payloads, map gestures that avoid rebuilding geometry on every tick, and measurable budgets. AI features, realtime collaboration, and deeper world authoring remain future work.