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:
- Keep the foundation and contributor runway stable.
- Make the lore graph useful through projects, entities, relationships, and search.
- Make continuity and change tracking coherent.
- Make secrets, knowledge, and visibility safe enough to use.
- Add collaboration after the visibility model is credible.
- 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
- What works today? summarizes implemented behavior.
- How do I try it? gives the local development commands.
- Product Goals explains what belongs in the core and what should remain outside it.
- Roadmap describes the current product sequence and status.
- Documentation and Test Standards explains how to keep tests and docs meaningful.
- Maintainer-Led Governance explains decision boundaries.
- Architecture Overview explains the major crates and boundaries.
- Recommended Rust Workspace explains the workspace layout.
- API Design describes the HTTP surface.
- Frontend UX Roadmap explains the first frontend workflows.
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:
- Pick work that fits the current roadmap horizon or fixes clearly observable behavior.
- Keep the patch focused enough to review.
- Add tests for important behavior when code changes affect behavior.
- Update docs only for actual behavior, accepted decisions, or clearly marked plans.
- 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
| Status | Meaning |
|---|---|
| Current | Active design or implementation work exists in the repository. |
| Next | Needed after the current horizon to make the preview meaningfully better. |
| Later | Valuable, but not needed to prove the core workflow. |
| Reserved | Planned 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
- Store projects as structured, searchable lore data.
- Track relationships between characters, factions, locations, facts, secrets, events, and plot threads.
- Support multiple continuities, campaigns, stories, or publications using the same base project.
- Track what different people or perspectives know, including players, player characters, factions, NPCs, and readers.
- Support collaboration with permissions.
- Allow system-specific rules data without making the project or continuity model depend on one game system.
- 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.
Recommended Rule
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 pointsCONTRIBUTING.md: contributor workflow and expectationsdoc/src/users/: user-facing product and workflow docsdoc/src/contributors/: contribution standards and maintainer expectationsdoc/src/concepts/: product concepts and vocabularydoc/src/architecture/: current architecture and technical designdoc/src/roadmap/: roadmap horizons and statusdoc/src/api/: API design and query behaviordoc/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:
- Keep
Projectas the root lore container. - Keep
Continuityas the continuity boundary. - Route-scope the API around the new root.
- Move events, chronology entries, and mutations under continuities.
- 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?
Navigation Model
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:
- Find information quickly.
- Understand relationships easily.
- Navigate naturally.
- Discover relevant information without searching for it.
- 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
- Architecture Overview
- Recommended Rust Workspace
- Crate Boundaries
- Domain Model
- API Design
- 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
- Keep domain logic out of route handlers.
- Use application services for use cases.
- Keep DTOs separate from domain structs when public API stability matters.
- Make continuity state explicit in routes.
- 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.
Basic Search
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.