Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

What Is TTRPG Forge?

TTRPG Forge is a public-preview, maintainer-led alpha for managing structured lore, branchable continuities, campaigns, stories, secrets, events, and player-facing knowledge.

The goal is to help creators treat a setting as more than folders of notes. A project becomes a living lore graph: people, places, groups, events, facts, secrets, disclosures, and changes over time.

What It Does

TTRPG Forge is being built around questions creators need to answer during prep, play, writing, and publication:

  • What exists in this project?
  • Who is connected to whom?
  • What happened in this continuity?
  • What changed from another branch?
  • What does this player, character, faction, or reader know?
  • Which secrets have been revealed, and to whom?

The core model is intentionally not tied to one game system. Rules systems such as D&D 5e, D&D 3.5e, Pathfinder, Hero System, or custom systems should sit around the core as adapters instead of defining the project model.

Current Status

TTRPG Forge is currently an early Rust workspace with a REST API, domain/application/storage crates, a Leptos frontend, and this mdBook site.

The current local preview can run seeded development data and expose projects, continuities, entities, relationships, secrets, continuity events, chronology entries, mutations, and search through the API and early frontend screens.

The current development focus is the transition from foundation into the first useful lore graph workflows:

  • projects and continuities
  • entities and relationships
  • events, chronology, and mutations
  • secrets, knowledge, and visibility
  • search and information retrieval
  • contributor-friendly crate boundaries

The product is not yet ready as a hosted public app. The near-term aim is a local development preview that proves the data model and the core user workflows.

Planned: Audience-specific visibility, collaboration, rules adapters, publication, and export are product direction. They should not be documented as completed user workflows until implemented.

For Different Audiences

If you want to know what works now, start with What works today?.

If you want to run it locally, start with How do I try it?.

If you are evaluating TTRPG Forge as a future user, start with Who is it for?. That page explains the intended workflows and current user-facing limits.

If you want to contribute, start with How do I contribute?. That page points to the architecture, product direction, local development setup, and the parts of the roadmap where help is most useful.

If you want to understand the technical design, start with Architecture Overview.

Roadmap

The short version uses horizons instead of dates:

  1. Keep the foundation and contributor runway stable.
  2. Make the lore graph useful through projects, entities, relationships, and search.
  3. Make continuity and change tracking coherent.
  4. Make secrets, knowledge, and visibility safe enough to use.
  5. Add collaboration after the visibility model is credible.
  6. Add publication, export, adapters, screenshots, social links, and signup surfaces when there is real product material to show.

See Roadmap for the audience-facing roadmap and Implementation Roadmap for the engineering sequence.

What Works Today?

TTRPG Forge is currently a local development preview. It is useful for exercising the model and contributor workflow, not for production use.

You Can Run

  • an Axum REST API on 127.0.0.1:8080
  • a Leptos frontend on 127.0.0.1:1420
  • seeded in-memory development storage
  • optional Postgres storage with migrations and seed data
  • mdBook documentation

You Can Model

  • projects
  • continuities
  • entities
  • relationships
  • secrets
  • continuity events
  • chronology entries
  • continuity mutations

You Can Do Through The API

  • list, create, view, and update projects
  • list, create, view, and update continuities
  • list, create, view, and update entities
  • list, create, and view relationships
  • list, create, view, and update secrets
  • list, create, view, and update continuity events
  • list, create, and view chronology entries
  • list, create, and view continuity mutations
  • search project content

You Can Do Through The Frontend

The frontend is an early validation surface. It currently focuses on:

  • opening projects
  • viewing project overviews
  • viewing entity detail pages
  • viewing continuity detail pages
  • searching project content

Important Limits

  • Authentication uses development headers.
  • Authorization is not production-ready.
  • Audience-specific visibility is not a complete user-facing workflow.
  • Collaboration is planned, not complete.
  • Rules adapters, publication, and export are planned, not complete.
  • The app is not a hosted public product.

How Do I Try It?

Install Prerequisites

Install Rust, then add the WebAssembly target:

rustup target add wasm32-unknown-unknown

Install the frontend and documentation tools:

cargo install trunk mdbook

Run The Local Preview

Start the API and frontend together:

cargo run -p xtask -- dev

Open:

http://127.0.0.1:1420/

The API listens at:

http://127.0.0.1:8080/

The frontend proxies /api/v1/ to the API server.

Storage Options

Postgres is optional for local development. If DATABASE_URL is not set in a debug build, the API uses seeded in-memory storage.

Force in-memory storage:

FORGE_STORE=memory cargo run -p forge-server

Use Postgres:

DATABASE_URL=postgres://user:password@localhost:5432/ttrpg_forge cargo run -p forge-server

In development mode, the Postgres store runs migrations and seeds development data on startup.

Development Authentication

Development authentication currently uses request headers:

x-user-id: 00000000-0000-0000-0000-000000000001
x-user-name: Development User

The web client sets these headers centrally while real authentication is deferred.

Common Commands

cargo run -p xtask -- fmt
cargo run -p xtask -- check
cargo run -p xtask -- test
cargo run -p xtask -- build
cargo run -p xtask -- docs

For Contributors

TTRPG Forge is an early Rust workspace in public preview / maintainer-led alpha. Contributors should expect the project shape to keep changing while the core model is proven.

The most useful contributions are the ones that strengthen the product’s central promise: a living lore graph with branchable continuities and audience-specific visibility.

Contributor Entry Points

Current Contribution Focus

The highest-value work is still foundational:

  • keeping project and continuity boundaries clear
  • making entities, relationships, events, and secrets consistent across API, storage, and UI
  • improving search and query behavior
  • tightening tests around domain rules and HTTP behavior
  • making the frontend answer project questions quickly
  • documenting decisions as the model stabilizes

Contribution Runway

The preferred path is intentionally lightweight:

  1. Pick work that fits the current roadmap horizon or fixes clearly observable behavior.
  2. Keep the patch focused enough to review.
  3. Add tests for important behavior when code changes affect behavior.
  4. Update docs only for actual behavior, accepted decisions, or clearly marked plans.
  5. Run the relevant xtask checks before sharing the patch.

If a change needs product direction first, open the design question before doing a large implementation.

Issue And Pull Request Templates

The repository includes Forgejo templates as optional conveniences for:

  • bug reports
  • documentation issues
  • feature proposals
  • maintenance work
  • pull requests

Use them when they fit. Blank issues are allowed.

Feature proposals should answer the project fit questions:

  • how does this support structured lore, branchable continuities, audience-specific visibility, search, or contributor readiness?
  • who benefits?
  • what is explicitly not being done?
  • what observable behavior would make it complete?
  • what docs or tests need to change?

Local Development

The full repository also has root-level README.md and CONTRIBUTING.md files for code-hosting views. In this documentation site, the local setup is covered by How do I try it?.

The short version is:

cargo run -p xtask -- dev

That starts the API and Leptos frontend together. Documentation can be rebuilt with:

cargo run -p xtask -- docs

Collaboration Boundary

User-facing material should describe outcomes and workflows. Contributor-facing material should describe implementation details, tradeoffs, crate boundaries, and unresolved design questions.

When adding new docs, place them according to that audience first. If a page serves both audiences, link to it from both sections but write it in the language of its primary reader.

Maintainer Boundary

Feedback and patches are welcome. Final direction, roadmap priority, and architecture decisions remain maintainer-owned while the project is in alpha.

Security Findings

See the repository SECURITY.md.

Roadmap

This roadmap uses horizons instead of fake dates. The guiding product bet is:

Creators need a living lore graph with branchable continuities and audience-specific knowledge.

Status Legend

StatusMeaning
CurrentActive design or implementation work exists in the repository.
NextNeeded after the current horizon to make the preview meaningfully better.
LaterValuable, but not needed to prove the core workflow.
ReservedPlanned site or product area that should stay empty until there is real material.

Horizon 0: Foundation

Status: Current

This horizon proves that the codebase, docs, and local workflow can support contributors.

Current repository behavior includes:

  • separated domain, application, storage, HTTP, frontend, and xtask crates
  • Axum REST API under /api/v1
  • Leptos frontend served by Trunk
  • in-memory development storage when Postgres is not configured
  • optional Postgres storage with migrations and development seed data
  • mdBook documentation under doc/src
  • shared xtask commands for formatting, checking, testing, building, docs, and local dev

Meaningful completion looks like:

  • README answers the project identity and contributor runway questions
  • contribution and governance docs are short and accurate
  • docs distinguish current behavior from planned behavior
  • project-scoped routes and development data remain easy to run locally

Horizon 1: Lore Graph Local Preview

Status: Current

This horizon proves that TTRPG Forge is more than a note collection.

Current or near-current behavior includes:

  • create, list, view, and update projects
  • create, list, view, and update entities
  • create, list, and view relationships
  • search project content
  • show project and entity detail pages in the frontend

Meaningful completion looks like:

  • entity and relationship workflows are consistent across API, storage, and UI
  • search is useful enough to be a primary retrieval path
  • project and entity pages answer common creator questions quickly
  • tests cover important domain, storage, query, and HTTP behavior

Horizon 2: Continuity and Change Tracking

Status: Next

This horizon proves that one project can support divergent campaign, story, or publication state.

Current or near-current behavior includes continuity resources, continuity-scoped events, chronology entries, and mutations. The work is not finished until the workflows are coherent in the UI and well covered by tests.

Meaningful completion looks like:

  • create, list, view, and update continuities
  • branch or derive a continuity from an existing continuity
  • record continuity-scoped events
  • attach events to chronology
  • record mutations
  • view current continuity state
  • explain the continuity model clearly in user and contributor docs

Horizon 3: Secrets, Knowledge, and Visibility

Status: Next

This horizon proves that the project can track information boundaries.

Current behavior includes secret resources. Audience-specific visibility and knowledge workflows are still planned.

Planned: The items below describe intended behavior. They are not complete user-facing workflows yet.

Meaningful completion looks like:

  • create hidden facts or secrets
  • associate knowledge with players, characters, factions, readers, or audiences
  • reveal information intentionally
  • filter views by audience
  • represent false or uncertain beliefs
  • make visibility and permissions difficult to bypass accidentally

Horizon 4: Collaboration

Status: Later

This horizon makes the project useful for groups without losing control over sensitive information.

Planned: Collaboration design should follow the visibility model instead of preceding it.

Meaningful completion looks like:

  • collaborator roles
  • project permissions
  • audit trail
  • comments or review notes
  • clear separation between owner, editor, viewer, and player-facing access

Horizon 5: Publication, Export, and Integrations

Status: Later

This horizon turns private project data into useful external outputs.

Planned: These features should not shape the core model until the lore graph, continuity, and visibility workflows are proven.

Meaningful completion looks like:

  • player handouts
  • public project or story pages
  • markdown export
  • JSON archive export
  • optional rules adapters
  • optional integrations with VTTs or campaign tools

Reserved Public-Facing Areas

Keep these reserved until there is real material:

  • screenshots once the first workflows are visually coherent
  • social links once public project channels exist
  • email signup or waitlist once there is a specific preview, release, or hosted option to announce
  • user-facing release notes once builds are useful outside development

Non-Goals For The First Preview

The first preview does not need:

  • a rules engine
  • graph visualization
  • map tools
  • dice rolling
  • character sheet replacement
  • hosted multi-tenant production deployment

Engineering Roadmap

The detailed engineering sequence remains in Implementation Roadmap. That page keeps the phase-by-phase technical checklist, while this page tracks what each horizon should make possible for users and collaborators.

For Users

TTRPG Forge is for people building and running narrative worlds: game masters, worldbuilders, authors, campaign organizers, and people publishing setting material.

The product goal is to make setting information easier to retrieve, compare, branch, and reveal than it is in documents, spreadsheets, notebooks, or static wikis.

Intended Use Cases

  • Organize private worldbuilding notes as structured lore.
  • Track characters, factions, locations, events, facts, secrets, and relationships.
  • Run campaigns where player knowledge differs from creator knowledge.
  • Branch a continuity when a campaign, story, or publication diverges from the base project.
  • Prepare player-facing journals, handouts, summaries, and setting references.
  • Reuse one project across campaigns, stories, publications, and rules systems.

What Makes It Different

Most note tools are good at storing text. TTRPG Forge is aimed at storing state:

  • what is true in the project
  • what changed in a continuity
  • what an audience can see
  • what a character or faction knows
  • how entities, events, and secrets connect

That distinction matters when a creator needs to answer a question quickly during a live session or maintain multiple versions of the same setting.

Planned Site Areas

This documentation site is also the starting point for a simple public project site. These areas are intentionally reserved now so the site can grow without mixing audiences:

Planned: The areas below should stay clearly marked until there is real product material to show.

  • screenshots of the app once the first workflows are worth showing
  • social links once public project channels exist
  • email signup or waitlist once there is a concrete preview or release cadence
  • user-facing release notes when builds become useful outside development

Not Yet

TTRPG Forge is not currently intended to replace a full virtual tabletop, dice roller, map renderer, or character sheet app.

Those features may become integrations later. The first useful version should focus on structured lore, continuity, visibility, and retrieval.

Product Goals

ttrpg-forge should help creators organize dynamic narrative projects as living lore graphs with branchable continuities.

Primary Goals

  1. Store projects as structured, searchable lore data.
  2. Track relationships between characters, factions, locations, facts, secrets, events, and plot threads.
  3. Support multiple continuities, campaigns, stories, or publications using the same base project.
  4. Track what different people or perspectives know, including players, player characters, factions, NPCs, and readers.
  5. Support collaboration with permissions.
  6. Allow system-specific rules data without making the project or continuity model depend on one game system.
  7. Make information fast to retrieve during a live session.

Non-Goals for the Core

The core should not begin as a full virtual tabletop, dice roller, map renderer, character sheet replacement, or rules engine for one specific game system.

Those may become integrations or optional crates later. The first version should focus on the part most tools handle poorly: structured lore, continuity, and disclosure state.

Useful Question

When adding a feature, ask:

Does this help a creator understand, search, mutate, or present the state of a project?

If the answer is no, it may belong in an integration crate instead of the core service.

In the target model, read “story” broadly here: the creator may be working with a project, continuity, campaign, publication, or narrative presentation.

What Is It Not Trying To Be?

TTRPG Forge is focused on structured lore, continuity, visibility, retrieval, and future publication/export paths.

The core project is not trying to become:

  • a virtual tabletop
  • a dice roller
  • a tactical map renderer
  • a character sheet replacement
  • a rules engine for one specific game system
  • a generic wiki with a different coat of paint

Those features may become integrations, adapters, or optional companion crates later. They should not define the core model.

Design Rule

If a feature does not help creators understand, search, mutate, or present the state of a project, it probably does not belong in the core service.

Core Concepts

The system should separate narrative concepts from rules concepts.

Narrative Layer

The narrative layer is system-neutral. It contains things that matter in almost any project format.

Examples:

  • Project
  • Continuity
  • Project
  • Continuity
  • Character
  • Faction
  • Location
  • Event
  • Fact
  • Secret
  • Plot thread
  • Chronology
  • Relationship
  • Scene
  • Mutation

Rules Layer

The rules layer is system-specific. It attaches game mechanics to narrative entities.

Examples:

  • D&D 5e stat block
  • Pathfinder hazard
  • Hero System character build
  • encounter difficulty
  • monster template
  • spell list
  • item mechanics

Presentation Layer

The presentation layer decides how information is shown.

Examples:

  • GM dashboard
  • player handout
  • continuity wiki
  • published setting page
  • book outline
  • API response

Design Rule

Do not make narrative entities depend on one rules system.

A character should exist even if they have no stat block. A city should exist even if no encounter happens there. A fact should exist even if it is hidden from every player. A continuity should be able to diverge without rewriting the base project.

Projects, Continuities, Stories, Campaigns, and Publications

The system should distinguish between a reusable project, a mutable continuity, a running campaign, a narrative story, and a published output.

Project

A project is the root lore container.

It contains reusable setting material: characters, factions, locations, entities, relationships, facts, secrets, events, and plot threads.

Example:

Project: The Silver Road

Continuity

A continuity is a mutable branch or version of a project.

A single project may have multiple continuities.

Example:

Project: The Silver Road
Continuity A: Main canon
Continuity B: Tuesday group
Continuity C: Online group

Each continuity can have its own state:

Main canon:
  mayor is alive
  guild hall stands
  secret tunnel undiscovered

Tuesday group:
  mayor is alive
  players joined the guild
  secret tunnel discovered

Online group:
  mayor is dead
  players burned the guild hall
  secret tunnel undiscovered

Campaign

A campaign is an interactive play workflow attached to a continuity, or a specialized kind of continuity if the product keeps the model simpler.

Campaigns add participants, sessions, player visibility, and table-specific outcomes.

Story

A story is a narrative presentation over a continuity.

Examples:

  • a novel draft
  • an adventure arc
  • a campaign journal
  • a serialized fiction outline

Publication

A publication is a curated view of project or story material.

Examples:

  • public setting guide
  • player handout
  • adventure module
  • novel outline
  • wiki export

Publications should not automatically reveal all private project data.

Treat the project as the source material. Treat continuities as branches of state and history. Treat stories, campaigns, and publications as presentations or workflows over that material.

Knowledge, Secrets, and Player Visibility

Facts, knowledge, and disclosure should be first-class data.

Many continuity tools store secrets as hidden text inside notes. That makes them hard to query. ttrpg-forge should model the underlying fact, who knows or believes it, and who is allowed to see it.

Fact

A fact is a claim about the project or a continuity.

Example:

Fact:
  The old bridge is unsafe.

Scope:
  Main canon

Secret

A secret is a fact or disclosure state that is hidden from some audiences.

Example:

Secret:
  The old bridge is unsafe.

Known by:
  bridge keeper
  town engineer

Unknown to:
  villagers
  player characters

Long term, Secret should usually be modeled as restricted disclosure around a fact rather than as an unrelated note.

Knowledge and Belief

Knowledge describes who knows or believes a fact and with what certainty.

Character -> knows -> Fact
Faction -> suspects -> Fact
PlayerCharacter -> falsely_believes -> Fact

Visibility

Visibility controls who can see data in the application.

Common visibility levels:

  • private to owner
  • visible to GMs
  • visible to collaborators
  • visible to specific players
  • visible to continuity participants
  • public

Belief vs Truth

The system should allow false beliefs.

Example:

Truth:
  The bridge failed because of poor maintenance.

Belief:
  The villagers think a monster damaged the bridge.

This allows mystery, propaganda, misinformation, and unreliable witnesses without corrupting the real project state.

Chronology and Change Tracking

A living project changes through branchable continuities. The system should track planned events, actual play events, and the mutations that make one continuity diverge from another.

Event

An event is something that happens or may happen in a continuity.

Examples:

Event: Festival begins
Event: Merchant caravan arrives
Event: Spy delivers letter
Event: Bridge collapses

Planned Chronology

The planned chronology answers:

What happens if nobody interferes?

Example:

Day 1: Festival begins
Day 2: Merchant caravan arrives
Day 3: Spy delivers letter
Day 4: Bridge collapses

Continuity Chronology

A continuity chronology records what actually happened at the table. More generally, a continuity chronology records what happened in that continuity.

Example:

Session 3:
  Players repaired the bridge before the caravan arrived.

Mutations

A mutation changes continuity state.

Examples:

Character status: alive -> dead
Faction influence: 60 -> 45
Secret visibility: hidden -> discovered by party
Location status: safe -> occupied

Design Recommendation

Use an event log for important changes.

Do not only store the current state. Store the reason the state changed.

Example:

Mutation:
  target: Bridge
  field: status
  old: unsafe
  new: repaired
  caused_by: Session 3 bridge repair

This makes continuity history auditable and allows future features like undo, branching chronologies, recaps, and publication history. Base project lore should remain reusable. Divergent outcomes should be represented in continuities, chronology entries, and mutations.

Simple Example

This example uses a small generic project.

Project

Project: The Broken Road

Entities

Character: Mara
  summary: A town guard who wants to keep the road safe.

Faction: Road Guild
  summary: A trade group that maintains the main road.

Location: Old Bridge
  summary: A damaged bridge outside town.

Fact: The bridge foundation is cracked.

Event: Caravan arrival
  summary: A caravan is expected tomorrow.

Relationships

Mara -> belongs_to -> Town Guard
Road Guild -> maintains -> Old Bridge
Mara -> knows -> Fact: The bridge foundation is cracked
Caravan arrival -> depends_on -> Old Bridge

Planned Chronology

Day 1: Players arrive in town.
Day 2: Caravan reaches the old bridge.
Day 3: Bridge may collapse if not repaired.

Continuity Mutation

If the players repair the bridge:

Mutation:
  target: Old Bridge
  field: status
  old: unsafe
  new: repaired
  reason: Players repaired the bridge before the caravan arrived.

If the players ignore it:

Mutation:
  target: Old Bridge
  field: status
  old: unsafe
  new: collapsed
  reason: Caravan crossed the bridge before repairs were made.

Why This Is Useful

The same project data can answer:

Who knows the bridge is unsafe?
What events depend on the bridge?
Which faction maintains the bridge?
What changed in this continuity?
What should players be allowed to see?

Documentation and Test Standards

These standards are meant to keep the project useful for contributors without turning it into process theater.

Documentation Standard

Document actual behavior first.

Good documentation should answer one of these questions:

  • What can a user or contributor do today?
  • What behavior does the code currently provide?
  • What decision has been made, and why?
  • What is planned, and how clearly is it marked as planned?
  • What is intentionally out of scope?

Avoid docs that read like completed product copy when the behavior does not exist.

Mark Planned Work

Use a short callout when documenting plans, design intent, or reserved sections:

> Planned: This describes intended behavior. It is not implemented yet.

Use a different callout for unsettled design:

> Open question: This design has not been decided yet.

If a page mixes current and planned behavior, put the current behavior first and label planned sections directly.

Keep Docs Structured By Audience

User-facing docs should explain workflows, current capabilities, limitations, and what the project is trying to become.

Contributor-facing docs should explain setup, architecture, crate boundaries, roadmap context, standards, and open design questions.

Architecture docs should describe current boundaries and decisions. If they describe a target shape, mark it as planned or recommended.

Design notes should explain why a choice was made, what alternatives were considered, and what would cause the project to revisit the choice.

Documentation Locations

  • README.md: project identity, current status, quick start, contribution entry points
  • CONTRIBUTING.md: contributor workflow and expectations
  • doc/src/users/: user-facing product and workflow docs
  • doc/src/contributors/: contribution standards and maintainer expectations
  • doc/src/concepts/: product concepts and vocabulary
  • doc/src/architecture/: current architecture and technical design
  • doc/src/roadmap/: roadmap horizons and status
  • doc/src/api/: API design and query behavior
  • doc/src/operations/: local operations and development notes

Test Standard

Tests should focus on behavior that matters.

Prefer tests for:

  • domain invariants and validation
  • application service behavior
  • storage contract behavior
  • HTTP status codes, request/response shape, routing, and error cases
  • query parsing and filtering behavior
  • regressions that affected real behavior

Avoid tests that only assert implementation details, duplicate the code line-by-line, or make refactoring harder without protecting behavior.

Test Names

Use test names that describe the behavior:

#![allow(unused)]
fn main() {
#[test]
fn creating_project_requires_non_empty_name() {
    // ...
}
}

Prefer externally visible language over internal mechanics when possible.

When Behavior Is Ambiguous

Do not invent behavior in tests or docs just to make a gap look complete.

Instead:

  • add a small test for the behavior that is already clear
  • mark the uncertainty as an open question in docs
  • propose the decision separately when it affects product direction

Review Checklist

Before merging docs or tests, ask:

  • Is this describing implemented behavior, a decision, or a clearly marked plan?
  • Would a new contributor know what to do next?
  • Does the test protect meaningful behavior?
  • Does the test make future refactoring harder for no product benefit?
  • Is the documentation likely to become stale because it overpromises?

Maintainer-Led Governance

TTRPG Forge is currently a public preview / maintainer-led alpha.

The project welcomes issues, patches, questions, and design feedback. Final product direction, architecture decisions, roadmap priority, and release timing are owned by the maintainer.

Who Can Do What

Users and contributors can:

  • report bugs and confusing behavior
  • suggest improvements
  • propose design changes
  • submit patches
  • improve docs and tests
  • ask for clarification when behavior is ambiguous

The maintainer can:

  • accept, request changes to, or decline patches
  • decide roadmap order
  • make final product and architecture decisions
  • defer features that do not fit the current horizon
  • close discussions that are no longer useful

Feedback Loop

Feedback is most useful when it is concrete:

  • describe the workflow or failure
  • explain the expected behavior
  • point to the affected docs, route, UI, or crate
  • separate current bugs from future feature requests

Broad product feedback is welcome, but it may be deferred if it does not support the current roadmap horizon.

Project Fit Test

Feature proposals should answer:

  • how does this support structured lore, branchable continuities, audience-specific visibility, search, or contributor readiness?
  • who benefits?
  • what is explicitly not being done?
  • what observable behavior would make it complete?
  • what docs or tests need to change?

This is not meant to block small ideas. It is meant to keep proposals concrete enough to decide.

Design Boundary

This project is not design-by-committee at this stage.

That boundary exists to protect maintainer time and keep the alpha coherent while the core model is still being proven. Contributors do not need to agree with every decision to participate, but patches should fit the current direction unless a design change has been accepted first.

Decision Notes

When a decision is large enough to affect future contributors, record it in the docs near the affected area. Keep decision notes short:

  • decision
  • reason
  • rejected alternatives if useful
  • what would cause reconsideration

Implementation Roadmap

This roadmap keeps the first version focused on the product’s core value:

A living lore graph with branchable continuities.

The codebase now uses Project for the root lore object and Continuity for a mutable continuity or branch.

Phase 1: Service Skeleton

  • add domain crate
  • add application crate
  • add HTTP API crate
  • add storage crate
  • add Postgres storage crate
  • add migrations
  • add basic tracing
  • add xtask check baseline

Phase 2: Accounts, Workspaces, and Projects

  • account model
  • workspace membership
  • project model
  • ownership
  • project list for current user
  • create and edit projects

Phase 3: Lore Graph

  • entity model
  • relationship model
  • basic graph queries
  • entity search
  • relationship search
  • tags and flexible properties
  • route-scoped API

Start concrete with entity-to-entity relationships, but keep the long-term model open to resource-to-resource relationships. Events, facts, scenes, publications, and other future resources may need to participate in the graph.

Phase 4: Continuities and Mutable Continuity

  • continuity model
  • branch from an existing continuity
  • events scoped to continuity
  • chronology entries scoped to continuity
  • mutation log scoped to continuity
  • current continuity state views

Campaign can either become a kind of continuity or become a play workflow attached to a continuity. The important design move is that divergent state belongs to a continuity boundary, not directly to the base project.

Phase 5: Facts, Knowledge, and Disclosure

  • fact model
  • belief and knowledge model
  • visibility and disclosure model
  • reveal secret workflow
  • player, reader, and point-of-view filtering
  • false belief support

The current Secret and Knowledge types are a useful prototype. Long term, a secret should usually be a fact or disclosure state with restricted visibility, while knowledge should describe who believes or knows a fact and with what certainty.

Phase 6: Collaboration

  • collaborator roles
  • permissions
  • audit trail
  • comments or review notes

Phase 7: Rules Adapters

  • rules adapter traits
  • generic stat attachment
  • D&D 5e proof of concept
  • Pathfinder proof of concept

Phase 8: Publication and Export

  • public project and story pages
  • player handouts
  • markdown export
  • JSON archive export

Suggested MVP

The smallest useful MVP is:

login
create workspace
create project
create entities
link entities
search entities
create continuity
record continuity event
record mutation
filter by visibility

A slightly stronger MVP is:

login
create workspace
create project
create entities
link entities
search entities
create continuity
record event
attach event to chronology
record mutation
create hidden fact or secret
reveal fact or secret to an entity or audience
filter by visibility

Do not start with a full rules engine. The unique value is the living lore graph with branchable continuities.

Immediate Refactor Direction

Before adding every missing roadmap feature, keep the root concepts aligned:

  1. Keep Project as the root lore container.
  2. Keep Continuity as the continuity boundary.
  3. Route-scope the API around the new root.
  4. Move events, chronology entries, and mutations under continuities.
  5. Keep entities and relationships project-scoped until divergent state is needed.

Frontend Direction

The first frontend should validate whether users can answer project and continuity questions quickly. Start with project list, project detail, and entity detail screens, then make search a primary workflow before investing in graph visualization.

See Frontend UX Roadmap for the user experience principles and initial screen scope.

Frontend UX Roadmap

The frontend should help game masters, worldbuilders, authors, and campaign organizers answer questions about their projects quickly and reliably.

The primary value of the frontend is not data entry. The primary value is information retrieval. Users should find answers faster than they could with documents, spreadsheets, wikis, or notebooks.

Core Philosophy

Organize the interface around questions, not tables.

The backend stores projects, continuities, entities, relations, facts, secrets, and events. Users should not need to think in those storage concepts. They think in project, continuity, and story questions.

Character questions:

  • Who is this person?
  • What are they trying to accomplish?
  • Who are they connected to?
  • What secrets do they know?
  • What events were they involved in?

Organization questions:

  • Who belongs to this organization?
  • Who leads it?
  • What conflicts is it involved in?
  • What events affected it?

Event questions:

  • What happened?
  • Why did it happen?
  • Who was involved?
  • What changed because of it?

Design Principles

Information Before Editing

The first screen should almost always be informational. Users spend more time reading information than creating it.

Selecting a character should show summary, relationships, chronology, secrets, and notes before presenting editing controls.

Minimize Context Switching

Users should not need to navigate through many screens to understand a topic. Related information should appear nearby, important relationships should be visible, and context should remain visible.

Avoid flows like:

Character -> Relationships Page -> Event Page -> Back

Prefer pages that keep the relevant context together:

Character Page
- Overview
- Relationships
- Recent Events
- Secrets

Optimize for Discovery

The interface should encourage exploration and help users discover information they were not specifically looking for.

Useful discovery surfaces include:

  • related entities
  • related events
  • shared relationships
  • linked secrets

Treat Search as a First-Class Feature

Search is one of the most valuable features in the system. Users should be able to locate any meaningful object quickly.

Search should eventually cover:

  • entities
  • events
  • organizations
  • locations
  • facts
  • secrets
  • continuities
  • campaigns

A user should never wonder where they put something.

Hide the Data Model

Users should not need to think about tables, foreign keys, entity relationships, or internal storage concepts. The interface should present information in project terms.

Initial Frontend Scope

The initial frontend should be intentionally small. Its purpose is validation, not completeness.

Project List

Purpose: allow users to discover and access projects.

Features:

  • list projects
  • create project
  • search projects
  • sort projects

Questions answered:

  • What projects exist?
  • Which one should I open?

Project Detail

Purpose: provide an overview of a project.

Sections:

  • overview
  • entities
  • relationships
  • continuities
  • facts and secrets

Questions answered:

  • What is this project about?
  • What content exists?

Continuity Detail

Purpose: show one continuity of a project.

Sections:

  • chronology
  • events
  • mutations
  • state changes
  • visibility-specific view

Questions answered:

  • What happened in this continuity?
  • What changed from the base project or parent continuity?

Entity Detail

Purpose: provide a complete view of a single entity.

Sections:

  • overview
  • relationships
  • chronology
  • secrets
  • notes

Questions answered:

  • Who is this?
  • Why do they matter?

Keep navigation simple and predictable:

Projects
└── Project
    ├── Overview
    ├── Entities
    ├── Relationships
    ├── Continuities
    └── Facts and Secrets
        └── Continuity
            ├── Chronology
            ├── Events
            └── Mutations

Search Roadmap

The search experience should feel like asking questions about the project.

For example, searching for Aldric should be able to return:

  • character: King Aldric
  • event: Coronation of Aldric
  • secret: Assassination Plot
  • relationship: Aldric -> Queen Elara

Search should become one of the highest priority frontend and API experiences after the basic project and entity views exist.

Graph Visualization

Graph visualizations are intentionally deferred.

Reasons:

  • high implementation cost
  • high UX complexity
  • limited value early in development

A graph view should only be implemented after search is complete, entity pages are mature, and relationship navigation is strong.

Technology Strategy

Current target:

REST API
+ Leptos frontend

Future target:

REST API
+ Leptos frontend
+ desktop client
+ mobile client

The frontend should remain a consumer of the API. Business logic should remain in backend services.

Success Criteria

The frontend is successful when a game master, worldbuilder, or author can:

  1. Find information quickly.
  2. Understand relationships easily.
  3. Navigate naturally.
  4. Discover relevant information without searching for it.
  5. Manage large projects without becoming overwhelmed.

The measure of success is not visual complexity. The measure of success is reducing the effort required to answer questions about a project, continuity, campaign, or story.

Lore Graph

Projects are mostly relationships, causality, facts, and changes over time. A graph model fits this better than a folder of notes.

Nodes

A node represents a meaningful resource in the project.

Common node types:

  • Character
  • Faction
  • Location
  • Item
  • Secret
  • Event
  • Scene
  • PlotThread
  • Continuity
  • Publication

Edges

An edge represents a relationship between two resources.

Examples:

Character -> belongs_to -> Faction
Faction -> controls -> Location
Character -> knows -> Secret
Event -> reveals -> Secret
Event -> advances -> PlotThread
Scene -> occurs_at -> Location
Character -> opposes -> Character
Faction -> funds -> Faction

Why This Matters

Graph relationships make questions easier to answer.

Examples:

Who knows this secret?
Which factions control locations near this city?
Which characters are connected to this plot thread?
What events were caused by this faction?
Which scenes can reveal this secret?

Implementation Note

The service does not have to use a graph database on day one. A relational database can model nodes and edges with tables.

A simple start:

entities
  id
  project_id
  entity_type
  name
  body
  metadata

relationships
  id
  project_id
  source_resource_id
  relation_type
  target_resource_id
  visibility
  metadata

The current code starts with entity-to-entity relationships. The target model should leave room for resource-to-resource relationships so events, facts, scenes, and publications can participate in the graph when needed.

Permissions and Collaboration

The service should support ownership, collaboration, campaign or continuity participation, and following.

User Relationships to a Project

A user may be:

  • owner
  • co-owner
  • editor
  • viewer
  • GM
  • player
  • follower

These are not all the same.

Ownership

The owner controls the project and can grant access.

Collaboration

Collaborators help create or manage project material.

Suggested roles:

Owner       full control
Editor      can create and edit project data
Commenter   can leave comments but not change canonical state
Viewer      can see private collaborator-visible data

Continuity Participation

Campaign participants are tied to a campaign or continuity, not necessarily the whole project.

Suggested roles:

GM          can view and mutate continuity state
AssistantGM can view GM notes and help prepare material
Player      can see player-visible continuity material
Spectator   can view selected public or shared material

Follows

Following is lightweight.

A follower may receive updates for public posts, publications, or continuity journals, but should not automatically gain access to private project or continuity state.

Permission Checks

Permission checks should happen in application services, not only in the UI.

Example:

Can this account reveal this secret to this continuity?
Can this account edit this entity?
Can this account view this relationship?
Can this account publish this page?

Audit Trail

For collaborative work, important mutations should record who made the change.

Example:

User A changed Location.status from safe to occupied.
User B revealed Secret X to Continuity Y.

Operational Notes

This project is a service, so operational concerns should be included early.

Suggested First Stack

A simple first production stack:

Rust service
Postgres database
Object storage for uploads
Reverse proxy
OIDC authentication provider

Authentication

Use an authentication boundary that can support multiple providers.

Possible approaches:

  • local accounts first
  • OIDC provider later
  • external identity provider from the beginning

Avoid spreading auth logic across route handlers.

Authorization

Authorization should be domain-aware.

Examples:

Can user view this secret?
Can user edit this continuity?
Can user publish this project page?
Can user mutate this chronology?

Migrations

Use database migrations from the start.

Recommended Rust-friendly options:

  • sqlx migrations
  • refinery
  • sea-orm migrations

Telemetry

Add tracing early.

Useful spans:

  • request ID
  • account ID
  • project ID
  • continuity ID
  • query type
  • permission decision

Backups

Project data is user-created content. Backups are not optional.

Minimum backup targets:

  • database
  • uploaded files
  • published exports

Import and Export

Plan for export early.

Useful formats:

  • JSON project export
  • Markdown export
  • player-facing HTML export
  • continuity archive export

Architecture

This section is for the technical structure behind TTRPG Forge: crate boundaries, domain modeling, API design, storage concerns, and query behavior.

Start here if you need to understand how the project is assembled before changing code.

Reading Order

  1. Architecture Overview
  2. Recommended Rust Workspace
  3. Crate Boundaries
  4. Domain Model
  5. API Design
  6. Search and Query Design

Design Bias

The core architecture should keep narrative concepts separate from delivery details.

That means:

  • domain rules belong in domain/application crates
  • persistence details belong behind storage traits
  • HTTP details belong in the API crate
  • frontend workflows should present user questions instead of internal table names
  • rules systems should attach around the core model instead of redefining it

Architecture Overview

ttrpg-forge should be organized around a system-neutral domain core.

A recommended high-level architecture:

ttrpg-forge
├── domain crates
├── application/service crates
├── storage crates
├── API crates
├── web UI crates
├── rules adapter crates
└── integration crates

Layers

Domain

Pure types and rules.

The domain should not know about HTTP, SQL, HTML, Axum, Tonic, Leptos, or authentication providers.

Application

Use cases and workflows.

Examples:

  • create project
  • add collaborator
  • reveal fact or secret to player
  • record continuity event
  • search continuity state
  • publish player-facing page

Infrastructure

Adapters for databases, search indexes, authentication, file storage, and message queues.

API

HTTP and gRPC entry points.

The API should call application services instead of directly mutating database tables.

UI

The web UI should consume the API or shared application contracts.

Rules Adapters

Rules adapters attach game-specific data to neutral narrative entities.

Examples:

D&D 5e adapter
Pathfinder adapter
Hero System adapter
Generic novel adapter

Important Boundary

The lore graph and continuity model should work without any rules adapter installed.

Recommended Rust Workspace

The initial rough idea is good, but the crates should be named around lifecycle and dependency direction.

A suggested layout:

ttrpg-forge/
├── Cargo.toml
├── crates/
│   ├── forge-domain/
│   ├── forge-application/
│   ├── forge-storage/
│   ├── forge-storage-postgres/
│   ├── forge-auth/
│   ├── forge-search/
│   ├── forge-api-contracts/
│   ├── forge-api-http/
│   ├── forge-api-grpc/
│   ├── forge-webui/
│   ├── forge-rules-core/
│   ├── forge-rules-dnd5e/
│   ├── forge-rules-pathfinder/
│   ├── forge-rules-hero/
│   └── forge-cli/
├── doc/
│   ├── book.toml
│   └── src/
└── deploy/

Suggested Workspace Dependencies

[workspace]
members = ["crates/*"]
resolver = "2"

[workspace.package]
edition = "2021"
license = "MIT OR Apache-2.0"
repository = "https://example.invalid/ttrpg-forge"

[workspace.dependencies]
anyhow = "1"
async-trait = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
time = { version = "0.3", features = ["serde"] }
uuid = { version = "1", features = ["serde", "v7"] }

Why Not minimal-api?

minimal-api describes the current implementation style, not the long-term responsibility.

Prefer names like:

forge-api-http
forge-api-grpc
forge-api-contracts

That lets the HTTP API grow beyond a minimal API without a crate rename.

Why Not Put Everything in core?

core often becomes a dumping ground.

Prefer clearer crates:

forge-domain       pure business types
forge-application  use cases
forge-storage      storage traits
forge-api-http     REST API

Crate Boundaries

Good crate boundaries make the project easier to change.

forge-domain

Contains pure domain types.

Examples:

  • ProjectId
  • ContinuityId
  • EntityId
  • EntityKind
  • RelationshipKind
  • Visibility
  • Secret
  • ChronologyEvent
  • Mutation

Should avoid:

  • SQL
  • HTTP
  • Axum
  • Tonic
  • UI code
  • database clients

forge-application

Contains use cases.

Examples:

  • CreateProject
  • AddEntity
  • AddRelationship
  • RevealSecret
  • RecordContinuityEvent
  • AddCollaborator

Depends on:

forge-domain
forge-storage
forge-auth traits, if needed

forge-storage

Contains repository traits.

Example:

#![allow(unused)]
fn main() {
#[async_trait::async_trait]
pub trait ProjectRepository {
    async fn get_project(&self, id: ProjectId) -> Result<Option<Project>, StorageError>;
    async fn save_project(&self, project: &Project) -> Result<(), StorageError>;
}
}

forge-storage-postgres

Implements storage traits using Postgres.

Depends on SQL libraries and migration tooling.

forge-api-contracts

Contains request and response DTOs shared by HTTP, gRPC, web UI, and tests.

forge-api-http

The REST API crate.

Recommended framework candidates:

  • Axum
  • Poem
  • Actix Web

forge-api-grpc

The gRPC API crate.

This can be added later with Tonic.

forge-webui

The browser UI.

Possible approaches:

  • Leptos
  • Dioxus
  • Yew
  • static frontend that consumes the API

forge-rules-core

Common traits and IDs for rules adapters.

forge-rules-dnd5e / forge-rules-pathfinder / forge-rules-hero

System-specific mechanics.

These should attach mechanics to project entities instead of owning the project model.

Domain Model

The domain model should represent reusable project structure, branchable continuity, and narrative presentation.

The current implementation uses Project as the root lore object and Continuity as the continuity branch. Story and Campaign remain useful product concepts, but they are presentations or workflows over continuities rather than the storage root.

Main Types

Account
Workspace
Project
Continuity
Story
Campaign
Publication
Entity
Relationship
Fact
Knowledge
Disclosure
Event
Chronology
Mutation
Permission

Account

An account represents a user of the service.

An account may own projects, participate in continuities or campaigns, collaborate on projects, or follow public stories and publications.

Workspace

A workspace is the collaboration and ownership boundary.

Workspace
  id
  owner_id
  name
  created_at
  updated_at

Project

A project is the root lore container.

Project
  id
  workspace_id
  title
  description
  status
  visibility
  created_at
  updated_at

Continuity

A continuity is a mutable branch or version of a project.

Continuity
  id
  project_id
  parent_continuity_id optional
  title
  status
  branch_point optional
  created_at
  updated_at

Story

A story is a narrative presentation over a continuity.

Story
  id
  project_id
  continuity_id
  title
  description
  status
  visibility
  created_at
  updated_at

Campaign

A campaign is an interactive play workflow attached to a continuity, or a specialized continuity if the implementation chooses a simpler model.

Campaign
  id
  project_id
  continuity_id
  title
  status
  rules_system
  created_at
  updated_at

Entity

An entity is a node in the lore graph.

Entity
  id
  project_id
  kind
  name
  summary
  body
  visibility
  metadata

Possible entity kinds:

Character
Faction
Location
Item
PlotThread
Concept
Species
Culture
Religion
Mystery

Relationship

A relationship is an edge in the lore graph.

Relationship
  id
  project_id
  source_resource_id
  relation_kind
  target_resource_id
  visibility
  metadata

Possible relationship kinds:

belongs_to
controls
knows
suspects
opposes
supports
funds
located_at
caused_by
reveals
advances

The first implementation may keep relationships entity-to-entity. The target model should allow resource-to-resource relationships.

Fact

A fact is a claim or assertion about a project or continuity.

Fact
  id
  project_id
  continuity_id optional
  subject_resource_id optional
  predicate
  object_resource_id optional
  literal_value optional
  truth_status
  visibility
  metadata

Knowledge

Knowledge records who knows, suspects, or falsely believes a fact.

Knowledge
  id
  project_id
  continuity_id optional
  knower_resource_id
  fact_id
  certainty
  learned_at_event_id optional
  source optional

Certainty values should include:

Rumor
Suspected
Known
FalseBelief

Disclosure

Disclosure records which audience can see a fact, secret, or resource in the application.

Disclosure
  id
  project_id
  target_resource_id
  audience_kind
  audience_id optional
  visibility

Secret should usually be treated as a fact or disclosure state with restricted visibility, not as the only way to represent hidden information.

Event

An event is something that happens or may happen in a continuity.

Event
  id
  project_id
  continuity_id
  title
  description
  status
  visibility
  created_at
  updated_at

Event statuses:

Planned
Possible
Occurred
Prevented
Failed

Chronology

A chronology positions events inside a continuity.

ChronologyEntry
  id
  project_id
  continuity_id
  event_id
  position_kind
  position_value

Mutation

A mutation records a continuity state change.

Mutation
  id
  project_id
  continuity_id
  target_id
  changed_field
  old_value
  new_value
  reason
  actor_id optional
  occurred_at

Visibility

Visibility should be explicit.

Private
OwnerOnly
GmOnly
Collaborators
ContinuityParticipants
SpecificAccounts
Public

Design Note

The first version can use JSON metadata for flexible fields. Once patterns become stable, promote important fields into typed columns or typed domain structs.

Keep base project lore separate from continuity-specific state. Entities and relationships can start project-scoped; events, chronology entries, and mutations should move under continuities as soon as the continuity model is introduced.

API Design

The service should begin with a REST API and leave room for gRPC later.

API Principles

  1. Keep domain logic out of route handlers.
  2. Use application services for use cases.
  3. Keep DTOs separate from domain structs when public API stability matters.
  4. Make continuity state explicit in routes.
  5. Make visibility and permissions impossible to ignore.

Example REST Routes

POST   /v1/projects
GET    /v1/projects
GET    /v1/projects/{project_id}
PATCH  /v1/projects/{project_id}

POST   /v1/projects/{project_id}/entities
GET    /v1/projects/{project_id}/entities
GET    /v1/projects/{project_id}/entities/{entity_id}
PATCH  /v1/projects/{project_id}/entities/{entity_id}

POST   /v1/projects/{project_id}/relationships
GET    /v1/projects/{project_id}/relationships

POST   /v1/projects/{project_id}/continuities
GET    /v1/projects/{project_id}/continuities
GET    /v1/projects/{project_id}/continuities/{continuity_id}

POST   /v1/projects/{project_id}/continuities/{continuity_id}/events
POST   /v1/projects/{project_id}/continuities/{continuity_id}/mutations
POST   /v1/projects/{project_id}/continuities/{continuity_id}/reveal

POST   /v1/projects/{project_id}/continuities
GET    /v1/projects/{project_id}/continuities

GET    /v1/me/projects
GET    /v1/me/continuities
GET    /v1/me/follows

API Contracts

Request and response types can live in forge-api-contracts.

Example:

#![allow(unused)]
fn main() {
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CreateProjectRequest {
    pub title: String,
    pub description: Option<String>,
}
}

gRPC Later

gRPC is useful for typed internal clients, desktop clients, or service-to-service integrations.

Do not block the first REST implementation waiting for gRPC unless a known client needs it.

Search and Query Design

Fast search is important during a live continuity.

Users should be able to quickly search by name, summary, body text, tags, and entity type.

Examples:

Find "bridge"
Find characters in this town
Find factions connected to this guild
Find secrets known by this NPC

Structured Queries

The graph model should support structured questions.

Examples:

entities where kind = Character and status = Alive
relationships where relation_kind = knows and target = Secret X
paths from Character A to Faction B
events affecting Location C

Search Index

Start simple:

  • Postgres full-text search
  • trigram search for fuzzy names
  • indexed entity type and project ID

Add a dedicated search engine later only when needed.

Useful Live Session Views

The UI should include fast views for:

  • recently used entities
  • active continuity threads
  • secrets not yet revealed
  • NPCs at current location
  • faction relationships
  • session chronology
  • unresolved consequences

Design Warning

A large wiki is not enough. The system should answer questions from structure, not only from text search.