# javilonte/rpg architecture

> Architecture diagram of the GitHub repository javilonte/rpg, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/javilonte/rpg
- Repository: https://github.com/javilonte/rpg

## Overview

D&D Virtual Tabletop is a browser-based multiplayer D&D 5e platform. Players authenticate, browse or join campaigns, and use a campaign play area for character sheets, maps, chat, dice, and turn-based combat. The shared rules engine supplies dice, character, combat, item, bestiary, map, and dungeon behavior; Supabase provides authentication, persistence, realtime capabilities, and server-side Edge Functions. The README documents several product capabilities whose implementation was not sampled, so those branches are shown at the documented subsystem level rather than with inferred call paths.

Main entry points: [`packages/engine/src/index.ts`](https://github.com/javilonte/rpg/blob/main/packages/engine/src/index.ts) (Rules engine exports), [`apps/web/src/components/play/play-layout.tsx`](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/play/play-layout.tsx) (Play layout), [`packages/engine/src/combat/index.ts`](https://github.com/javilonte/rpg/blob/main/packages/engine/src/combat/index.ts) (Combat rules), [`apps/web/src/app/page.tsx`](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/page.tsx) (Next.js app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_webapp["Next.js app<br/>[page.tsx]"]
  node_auth["Magic-link auth<br/>[auth.ts]"]
  node_callback["Auth callback<br/>[route.ts]"]
  node_campaigns["Campaign dashboard<br/>[page.tsx]"]
  node_play["Campaign play area<br/>[page.tsx]"]
  node_layout["Play layout<br/>[play-layout.tsx]"]
  node_characterui["Character sheet"]
  node_mapui["Map interface<br/>[map-view.tsx]"]
  node_combatui["Combat tracker<br/>[combat-tracker.tsx]"]
  node_diceui["Dice roller<br/>[dice-roller.tsx]"]
  node_chatui["Realtime chat<br/>[chat-panel.tsx]"]
end

subgraph group_platform["Supabase platform"]
  node_browserclient["Browser client<br/>[client.ts]"]
  node_serverclient["Server client<br/>[server.ts]"]
  node_supabase["Supabase services"]
  node_db[("Postgres database")]
  node_rollfn["Roll dice function<br/>[index.ts]"]
  node_startfn["Start combat function<br/>[index.ts]"]
  node_advancefn["Advance turn function<br/>[index.ts]"]
  node_damagefn["Apply damage function<br/>[index.ts]"]
end

subgraph group_rules["Rules engine"]
  node_engine["Rules engine exports<br/>[index.ts]"]
  node_dice["Dice rules<br/>[parser.ts]"]
  node_characters["Character rules<br/>[index.ts]"]
  node_combat["Combat rules<br/>[index.ts]"]
  node_bestiary["Monster bestiary<br/>[index.ts]"]
  node_items["Items and loot<br/>[index.ts]"]
  node_maps["Map rules<br/>[index.ts]"]
  node_dungeons["Dungeon generator<br/>[index.ts]"]
end

subgraph group_contracts["Shared contracts"]
  node_shared["Shared schemas<br/>[index.ts]"]
end

node_player(("Player"))

node_player -->|"uses"| node_webapp
node_webapp -->|"offers sign-in"| node_auth
node_auth -->|"creates client"| node_serverclient
node_callback -->|"creates client"| node_serverclient
node_callback -->|"exchanges session"| node_supabase
node_webapp -->|"opens dashboard"| node_campaigns
node_campaigns -->|"opens campaign"| node_play
node_play -->|"renders"| node_layout
node_layout -->|"renders"| node_characterui
node_layout -->|"renders"| node_mapui
node_layout -->|"renders"| node_combatui
node_layout -->|"renders"| node_diceui
node_layout -->|"renders"| node_chatui
node_browserclient -->|"connects"| node_supabase
node_serverclient -->|"connects"| node_supabase
node_supabase -->|"persists data"| node_db
node_rollfn -->|"parses and rolls"| node_dice
node_rollfn -->|"validates formula"| node_shared
node_startfn -->|"creates combat"| node_db
node_startfn -->|"rolls initiative"| node_combat
node_advancefn -->|"reads and updates"| node_db
node_advancefn -->|"advances turn"| node_combat
node_damagefn -->|"reads and updates"| node_db
node_damagefn -->|"calculates damage"| node_combat
node_engine -->|"exports"| node_dice
node_engine -->|"exports"| node_characters
node_engine -->|"exports"| node_combat
node_engine -->|"exports"| node_bestiary
node_engine -->|"exports"| node_items
node_engine -->|"exports"| node_maps
node_engine -->|"exports"| node_dungeons

click node_webapp "https://github.com/javilonte/rpg/blob/main/apps/web/src/app/page.tsx"
click node_auth "https://github.com/javilonte/rpg/blob/main/apps/web/src/app/actions/auth.ts"
click node_callback "https://github.com/javilonte/rpg/blob/main/apps/web/src/app/auth/callback/route.ts"
click node_campaigns "https://github.com/javilonte/rpg/blob/main/apps/web/src/app/campaigns/page.tsx"
click node_play "https://github.com/javilonte/rpg/blob/main/apps/web/src/app/play/%5BcampaignId%5D/page.tsx"
click node_layout "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/play/play-layout.tsx"
click node_characterui "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/character/character-sheet.tsx"
click node_mapui "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/map/map-view.tsx"
click node_combatui "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/combat/combat-tracker.tsx"
click node_diceui "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/dice/dice-roller.tsx"
click node_chatui "https://github.com/javilonte/rpg/blob/main/apps/web/src/components/chat/chat-panel.tsx"
click node_browserclient "https://github.com/javilonte/rpg/blob/main/apps/web/src/lib/supabase/client.ts"
click node_serverclient "https://github.com/javilonte/rpg/blob/main/apps/web/src/lib/supabase/server.ts"
click node_rollfn "https://github.com/javilonte/rpg/blob/main/supabase/functions/roll-dice/index.ts"
click node_startfn "https://github.com/javilonte/rpg/blob/main/supabase/functions/start-combat/index.ts"
click node_advancefn "https://github.com/javilonte/rpg/blob/main/supabase/functions/advance-turn/index.ts"
click node_damagefn "https://github.com/javilonte/rpg/blob/main/supabase/functions/apply-damage/index.ts"
click node_engine "https://github.com/javilonte/rpg/blob/main/packages/engine/src/index.ts"
click node_dice "https://github.com/javilonte/rpg/blob/main/packages/engine/src/dice/parser.ts"
click node_characters "https://github.com/javilonte/rpg/blob/main/packages/engine/src/character/index.ts"
click node_combat "https://github.com/javilonte/rpg/blob/main/packages/engine/src/combat/index.ts"
click node_bestiary "https://github.com/javilonte/rpg/blob/main/packages/engine/src/bestiary/index.ts"
click node_items "https://github.com/javilonte/rpg/blob/main/packages/engine/src/items/index.ts"
click node_maps "https://github.com/javilonte/rpg/blob/main/packages/engine/src/map/index.ts"
click node_dungeons "https://github.com/javilonte/rpg/blob/main/packages/engine/src/dungeon/index.ts"
click node_shared "https://github.com/javilonte/rpg/blob/main/packages/shared/src/index.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_webapp,node_auth,node_callback,node_campaigns,node_play,node_layout,node_characterui,node_mapui,node_combatui,node_diceui,node_chatui toneBlue
class node_browserclient,node_serverclient,node_supabase,node_db,node_rollfn,node_startfn,node_advancefn,node_damagefn toneAmber
class node_engine,node_dice,node_characters,node_combat,node_bestiary,node_items,node_maps,node_dungeons toneMint
class node_shared toneRose
class node_player toneIndigo
```

## Components

### Web experience

- [Next.js app](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/page.tsx): `apps/web/src/app/page.tsx`
- [Magic-link auth](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/actions/auth.ts): `apps/web/src/app/actions/auth.ts`
- [Auth callback](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/auth/callback/route.ts): `apps/web/src/app/auth/callback/route.ts`
- [Campaign dashboard](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/campaigns/page.tsx): `apps/web/src/app/campaigns/page.tsx`
- [Campaign play area](https://github.com/javilonte/rpg/blob/main/apps/web/src/app/play/%5BcampaignId%5D/page.tsx): `apps/web/src/app/play/[campaignId]/page.tsx`
- [Play layout](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/play/play-layout.tsx): `apps/web/src/components/play/play-layout.tsx`
- [Character sheet](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/character/character-sheet.tsx): `apps/web/src/components/character/character-sheet.tsx`
- [Map interface](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/map/map-view.tsx): `apps/web/src/components/map/map-view.tsx`
- [Combat tracker](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/combat/combat-tracker.tsx): `apps/web/src/components/combat/combat-tracker.tsx`
- [Dice roller](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/dice/dice-roller.tsx): `apps/web/src/components/dice/dice-roller.tsx`
- [Realtime chat](https://github.com/javilonte/rpg/blob/main/apps/web/src/components/chat/chat-panel.tsx): `apps/web/src/components/chat/chat-panel.tsx`

### Supabase platform

- [Browser client](https://github.com/javilonte/rpg/blob/main/apps/web/src/lib/supabase/client.ts): `apps/web/src/lib/supabase/client.ts`
- [Server client](https://github.com/javilonte/rpg/blob/main/apps/web/src/lib/supabase/server.ts): `apps/web/src/lib/supabase/server.ts`
- **Supabase services**
- **Postgres database**
- [Roll dice function](https://github.com/javilonte/rpg/blob/main/supabase/functions/roll-dice/index.ts): `supabase/functions/roll-dice/index.ts`
- [Start combat function](https://github.com/javilonte/rpg/blob/main/supabase/functions/start-combat/index.ts): `supabase/functions/start-combat/index.ts`
- [Advance turn function](https://github.com/javilonte/rpg/blob/main/supabase/functions/advance-turn/index.ts): `supabase/functions/advance-turn/index.ts`
- [Apply damage function](https://github.com/javilonte/rpg/blob/main/supabase/functions/apply-damage/index.ts): `supabase/functions/apply-damage/index.ts`

### Rules engine

- [Rules engine exports](https://github.com/javilonte/rpg/blob/main/packages/engine/src/index.ts): `packages/engine/src/index.ts`
- [Dice rules](https://github.com/javilonte/rpg/blob/main/packages/engine/src/dice/parser.ts): `packages/engine/src/dice/parser.ts`
- [Character rules](https://github.com/javilonte/rpg/blob/main/packages/engine/src/character/index.ts): `packages/engine/src/character/index.ts`
- [Combat rules](https://github.com/javilonte/rpg/blob/main/packages/engine/src/combat/index.ts): `packages/engine/src/combat/index.ts`
- [Monster bestiary](https://github.com/javilonte/rpg/blob/main/packages/engine/src/bestiary/index.ts): `packages/engine/src/bestiary/index.ts`
- [Items and loot](https://github.com/javilonte/rpg/blob/main/packages/engine/src/items/index.ts): `packages/engine/src/items/index.ts`
- [Map rules](https://github.com/javilonte/rpg/blob/main/packages/engine/src/map/index.ts): `packages/engine/src/map/index.ts`
- [Dungeon generator](https://github.com/javilonte/rpg/blob/main/packages/engine/src/dungeon/index.ts): `packages/engine/src/dungeon/index.ts`

### Shared contracts

- [Shared schemas](https://github.com/javilonte/rpg/blob/main/packages/shared/src/index.ts): `packages/shared/src/index.ts`

### Other components

- **Player**

## Connections

- Player → Next.js app: uses
- Next.js app → Magic-link auth: offers sign-in
- Magic-link auth → Server client: creates client
- Auth callback → Server client: creates client
- Auth callback → Supabase services: exchanges session
- Next.js app → Campaign dashboard: opens dashboard
- Campaign dashboard → Campaign play area: opens campaign
- Campaign play area → Play layout: renders
- Play layout → Character sheet: renders
- Play layout → Map interface: renders
- Play layout → Combat tracker: renders
- Play layout → Dice roller: renders
- Play layout → Realtime chat: renders
- Browser client → Supabase services: connects
- Server client → Supabase services: connects
- Supabase services → Postgres database: persists data
- Roll dice function → Dice rules: parses and rolls
- Roll dice function → Shared schemas: validates formula
- Start combat function → Postgres database: creates combat
- Start combat function → Combat rules: rolls initiative
- Advance turn function → Postgres database: reads and updates
- Advance turn function → Combat rules: advances turn
- Apply damage function → Postgres database: reads and updates
- Apply damage function → Combat rules: calculates damage
- Rules engine exports → Dice rules: exports
- Rules engine exports → Character rules: exports
- Rules engine exports → Combat rules: exports
- Rules engine exports → Monster bestiary: exports
- Rules engine exports → Items and loot: exports
- Rules engine exports → Map rules: exports
- Rules engine exports → Dungeon generator: exports
