# surelypal/propria architecture

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

- Interactive diagram: https://gitdiagram.com/surelypal/propria
- Repository: https://github.com/surelypal/propria

## Overview

Propria is a tabletop role-playing app combining live campaigns, configurable game rules and character sheets, template authoring, local multiplayer synchronization, guidebooks, and procedural music. The main user path is campaign setup or joining, character creation, then running a campaign through dynamic sheets and map/scene screens; the host-authoritative world applies rule-driven changes and syncs them to peers. The README is empty and sampled implementation is partial, so links between unsampled UI and runtime services are omitted rather than inferred.

Main entry points: [`Propria/Networking/NetworkSyncService.swift`](https://github.com/surelypal/propria/blob/dev/Propria/Networking/NetworkSyncService.swift) (Network sync), [`Propria/Template/World.swift`](https://github.com/surelypal/propria/blob/dev/Propria/Template/World.swift) (Game world), [`Propria/Music/MusicEngine.swift`](https://github.com/surelypal/propria/blob/dev/Propria/Music/MusicEngine.swift) (Procedural audio), [`Propria/Events/Events.swift`](https://github.com/surelypal/propria/blob/dev/Propria/Events/Events.swift) (Event bus)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_campaign["Campaign play"]
  node_campaignui["Campaign screens"]
  node_creationui["Character creation"]
  node_sheet["Dynamic character sheet"]
  node_scene["Map and scene UI"]
  node_runtime["Campaign runtime"]
  node_workspace["Campaign workspace<br/>[Workspace.swift]"]
end

subgraph group_rules["Rules and templates"]
  node_world["Game world<br/>[World.swift]"]
  node_authority["World authority"]
  node_entities[("Entity store<br/>[EntityStore.swift]")]
  node_events["Event bus<br/>[Events.swift]"]
  node_expressions["Expression engine"]
  node_registry["Game registry<br/>[Registry.swift]"]
  node_templateeditor["Template editor"]
  node_layouteditor["Layout editor"]
  node_templatecache[("Template packages<br/>[Workspace.swift]")]
end

subgraph group_sync["Campaign sync"]
  node_syncservice["Network sync"]
  node_transport["Peer transport"]
  node_provision["Campaign provisioning"]
end

subgraph group_media["Library and audio"]
  node_guidebook["Guidebooks<br/>[Guidebook.swift]"]
  node_musicdirector["Music director"]
  node_musicengine["Procedural audio<br/>[MusicEngine.swift]"]
  node_audiograph["Audio graph<br/>[AudioGraph.swift]"]
end

node_player(("Player or host"))

node_player -->|"opens campaigns"| node_campaignui
node_campaignui -->|"creates characters"| node_creationui
node_player -->|"uses campaign"| node_sheet
node_player -->|"runs encounters"| node_scene
node_world -->|"reads and updates"| node_entities
node_world -->|"emits events"| node_events
node_world -->|"evaluates formulas"| node_expressions
node_world -->|"uses definitions"| node_registry
node_authority -->|"applies changes"| node_entities
node_authority -->|"sends intents"| node_syncservice
node_syncservice -->|"broadcasts events"| node_events
node_syncservice -->|"sends messages"| node_transport
node_transport -->|"delivers messages"| node_syncservice
node_provision -->|"sends campaign messages"| node_syncservice
node_templateeditor -->|"edits layouts"| node_layouteditor
node_layouteditor -->|"loads package"| node_templatecache
node_player -->|"authors templates"| node_templateeditor
node_player -->|"reads guides"| node_guidebook
node_musicdirector -->|"modulates state"| node_musicengine
node_musicengine -->|"observes campaign events"| node_events
node_musicengine -->|"renders audio"| node_audiograph

click node_campaignui "https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/CampaignsView.swift"
click node_creationui "https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/Creation/CreationStepViews.swift"
click node_sheet "https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/DynamicScreenView.swift"
click node_scene "https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/SceneScreenView.swift"
click node_runtime "https://github.com/surelypal/propria/blob/dev/Propria/Campaign/CampaignRuntime.swift"
click node_workspace "https://github.com/surelypal/propria/blob/dev/Propria/Campaign/Workspace.swift"
click node_world "https://github.com/surelypal/propria/blob/dev/Propria/Template/World.swift"
click node_authority "https://github.com/surelypal/propria/blob/dev/Propria/Template/WorldAuthority.swift"
click node_entities "https://github.com/surelypal/propria/blob/dev/Propria/Core/EntityStore.swift"
click node_events "https://github.com/surelypal/propria/blob/dev/Propria/Events/Events.swift"
click node_expressions "https://github.com/surelypal/propria/blob/dev/Propria/Core/ExpressionEngine.swift"
click node_registry "https://github.com/surelypal/propria/blob/dev/Propria/Registry/Registry.swift"
click node_templateeditor "https://github.com/surelypal/propria/blob/dev/Propria/UI/Templates/TemplateEditorView.swift"
click node_layouteditor "https://github.com/surelypal/propria/blob/dev/Propria/UI/Templates/LayoutEditorView.swift"
click node_templatecache "https://github.com/surelypal/propria/blob/dev/Propria/Campaign/Workspace.swift"
click node_syncservice "https://github.com/surelypal/propria/blob/dev/Propria/Networking/NetworkSyncService.swift"
click node_transport "https://github.com/surelypal/propria/blob/dev/Propria/Networking/MultipeerTransport.swift"
click node_provision "https://github.com/surelypal/propria/blob/dev/Propria/Campaign/CampaignProvisioningService.swift"
click node_guidebook "https://github.com/surelypal/propria/blob/dev/Propria/Knowledge/Guidebook.swift"
click node_musicdirector "https://github.com/surelypal/propria/blob/dev/Propria/Music/MusicDirector.swift"
click node_musicengine "https://github.com/surelypal/propria/blob/dev/Propria/Music/MusicEngine.swift"
click node_audiograph "https://github.com/surelypal/propria/blob/dev/Propria/Music/AudioGraph.swift"

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_campaignui,node_creationui,node_sheet,node_scene,node_runtime,node_workspace toneBlue
class node_world,node_authority,node_entities,node_events,node_expressions,node_registry,node_templateeditor,node_layouteditor,node_templatecache toneAmber
class node_syncservice,node_transport,node_provision toneMint
class node_guidebook,node_musicdirector,node_musicengine,node_audiograph toneRose
class node_player toneIndigo
```

## Components

### Campaign play

- [Campaign screens](https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/CampaignsView.swift): `Propria/UI/Campaign/CampaignsView.swift`
- [Character creation](https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/Creation/CreationStepViews.swift): `Propria/UI/Campaign/Creation/CreationStepViews.swift`
- [Dynamic character sheet](https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/DynamicScreenView.swift): `Propria/UI/Campaign/DynamicScreenView.swift`
- [Map and scene UI](https://github.com/surelypal/propria/blob/dev/Propria/UI/Campaign/SceneScreenView.swift): `Propria/UI/Campaign/SceneScreenView.swift`
- [Campaign runtime](https://github.com/surelypal/propria/blob/dev/Propria/Campaign/CampaignRuntime.swift): `Propria/Campaign/CampaignRuntime.swift`
- [Campaign workspace](https://github.com/surelypal/propria/blob/dev/Propria/Campaign/Workspace.swift): `Propria/Campaign/Workspace.swift`

### Rules and templates

- [Game world](https://github.com/surelypal/propria/blob/dev/Propria/Template/World.swift): `Propria/Template/World.swift`
- [World authority](https://github.com/surelypal/propria/blob/dev/Propria/Template/WorldAuthority.swift): `Propria/Template/WorldAuthority.swift`
- [Entity store](https://github.com/surelypal/propria/blob/dev/Propria/Core/EntityStore.swift): `Propria/Core/EntityStore.swift`
- [Event bus](https://github.com/surelypal/propria/blob/dev/Propria/Events/Events.swift): `Propria/Events/Events.swift`
- [Expression engine](https://github.com/surelypal/propria/blob/dev/Propria/Core/ExpressionEngine.swift): `Propria/Core/ExpressionEngine.swift`
- [Game registry](https://github.com/surelypal/propria/blob/dev/Propria/Registry/Registry.swift): `Propria/Registry/Registry.swift`
- [Template editor](https://github.com/surelypal/propria/blob/dev/Propria/UI/Templates/TemplateEditorView.swift): `Propria/UI/Templates/TemplateEditorView.swift`
- [Layout editor](https://github.com/surelypal/propria/blob/dev/Propria/UI/Templates/LayoutEditorView.swift): `Propria/UI/Templates/LayoutEditorView.swift`
- [Template packages](https://github.com/surelypal/propria/blob/dev/Propria/Campaign/Workspace.swift): `Propria/Campaign/Workspace.swift`

### Campaign sync

- [Network sync](https://github.com/surelypal/propria/blob/dev/Propria/Networking/NetworkSyncService.swift): `Propria/Networking/NetworkSyncService.swift`
- [Peer transport](https://github.com/surelypal/propria/blob/dev/Propria/Networking/MultipeerTransport.swift): `Propria/Networking/MultipeerTransport.swift`
- [Campaign provisioning](https://github.com/surelypal/propria/blob/dev/Propria/Campaign/CampaignProvisioningService.swift): `Propria/Campaign/CampaignProvisioningService.swift`

### Library and audio

- [Guidebooks](https://github.com/surelypal/propria/blob/dev/Propria/Knowledge/Guidebook.swift): `Propria/Knowledge/Guidebook.swift`
- [Music director](https://github.com/surelypal/propria/blob/dev/Propria/Music/MusicDirector.swift): `Propria/Music/MusicDirector.swift`
- [Procedural audio](https://github.com/surelypal/propria/blob/dev/Propria/Music/MusicEngine.swift): `Propria/Music/MusicEngine.swift`
- [Audio graph](https://github.com/surelypal/propria/blob/dev/Propria/Music/AudioGraph.swift): `Propria/Music/AudioGraph.swift`

### Other components

- **Player or host**

## Connections

- Player or host → Campaign screens: opens campaigns
- Campaign screens → Character creation: creates characters
- Player or host → Dynamic character sheet: uses campaign
- Player or host → Map and scene UI: runs encounters
- Game world → Entity store: reads and updates
- Game world → Event bus: emits events
- Game world → Expression engine: evaluates formulas
- Game world → Game registry: uses definitions
- World authority → Entity store: applies changes
- World authority → Network sync: sends intents
- Network sync → Event bus: broadcasts events
- Network sync → Peer transport: sends messages
- Peer transport → Network sync: delivers messages
- Campaign provisioning → Network sync: sends campaign messages
- Template editor → Layout editor: edits layouts
- Layout editor → Template packages: loads package
- Player or host → Template editor: authors templates
- Player or host → Guidebooks: reads guides
- Music director → Procedural audio: modulates state
- Procedural audio → Event bus: observes campaign events
- Procedural audio → Audio graph: renders audio
