Go to file
2025-10-16 09:06:56 -05:00
.gitignore Inital project setup 2025-10-15 14:16:26 -05:00
rambling.md reverting project, revising structure 2025-10-16 09:06:56 -05:00
readme.md update readme.md 2025-10-15 19:14:32 -05:00

SessionZero Design Document

1. Introduction

1.1 Purpose

SessionZero is a free and open-source TTRPG companion app designed to streamline tabletop role-playing game management. It emphasizes flexibility, modularity, and federation through a system-agnostic datapack format, supporting both offline and self-hostable online play. The goal is to empower players and GMs with full control over their data, rulesets, and session management.

1.2 Scope

The project will begin as a cross-platform desktop application (Windows and Linux), offering tools for creating and managing TTRPG data such as characters, datasets, templates, and sessions. The backend supports user accounts, a database for shared content (SessionZeroDB), and prepares for future federation capabilities. Phase 2 introduces federation, while Phase 3 focuses on mobile support and plugin extensibility.

1.3 Objectives

  • Provide a modular, open-source companion app for any TTRPG system.
  • Implement a JSON-based datapack format for extensible content storage.
  • Support both local use and self-hostable online instances.
  • Create a foundation for future federation and mobile support.

2. System Overview

SessionZero consists of three main layers:

  1. Frontend (Client): Cross-platform desktop application (.NET Avalonia).
  2. Backend (Server): ASP.NET backend managing user accounts, SessionZeroDB, and P2P connections.
  3. Datapack System: A structured archive format for storing and sharing game data.

3. Functional Requirements

3.1 Core Features (Phase 1)

  • User Authentication: Email and password-based account creation and login.
  • Local Single-User Mode: Fully functional offline mode without any account. In offline/no-user sessions the local user assumes the GM role by default (GM can also act as a player).
  • Datapack Management:
    • Create, edit, and package datapacks.
    • Import/export datapacks.
    • Link media assets (e.g., images) within datapacks.
  • Data Creation/Editing:
    • Datasets, characters, character templates, and session templates.
  • Session Management:
    • GM control over player sheets and session datapacks.
    • Player view limited to their own characters.
    • Integrated chat/log system for simple in-session communication.
  • SessionZeroDB:
    • Database for hosting and retrieving community content.
    • Attribution and license information for each uploaded pack.

3.2 Federation (Phase 2)

  • Federated servers can communicate for global content discovery.
  • Configurable access controls for visibility (private, public, or indexed).
  • P2P session management.

3.3 Mobile/Plugin System (Phase 3)

  • Native mobile clients for Android/iOS.
  • Plugin architecture for extending UI and data management capabilities.

4. Non-Functional Requirements

  • Cross-Platform Support: Windows and Linux for MVP.
  • Performance: Efficient JSON parsing and fast local caching.
  • Scalability: Designed for multiple users per server instance.
  • Security: Hashed passwords, secure token authentication.
  • Data Portability: All user data exportable in open formats.

5. Datapack Specification

A datapack is a self-contained archive (.szp) that holds all data and assets for a specific TTRPG system, module, or expansion. It serves as the foundation for SessionZero's extensible content model. Each pack can define datasets, templates, and optionally contain instance data (though instances are usually stored separately as save files). The structure emphasizes modularity, portability, and reliable dependency management between packs.

5.1 Directory Structure

pack-name/
├── szpack.json                 # Pack metadata and manifest
├── media/
│   └── images/                 # Image assets (referenced by objects)
└── objects/
    ├── datasets/               # User-defined structured data (e.g. items, NPCs)
    ├── character-templates/    # Templates defining character structures
    └── session-templates/      # Templates defining session/campaign structures

5.2 Pack Metadata (szpack.json)

Each datapack contains a root metadata file that defines its identity, authorship, dependencies, and compatibility information.

{
  "id": "c9a3f9c8-8b8a-4f1f-9f3b-2d8c7f2c6c62",
  "name": "Example Pack",
  "version": "1.0.0",
  "author": "UserName",
  "license": "CC-BY-SA-4.0",
  "description": "A fantasy setting datapack containing items and NPCs.",
  "created": "2025-10-15T00:00:00Z",
  "sessionzeroVersion": "1.0.0",
  "dependencies": [
    {
      "id": "c2e6d0a4-2a8f-4a51-b36e-9f8f2c7b1d11",
      "version": ">=0.9 <2.0"
    }
  ]
}

Field notes:

  • id: Required. Stable UUID (v4) identifying this pack.
  • version: Required. Semantic version (MAJOR.MINOR.PATCH). Backwards-incompatible changes increment MAJOR.
  • sessionzeroVersion: Required. Minimum SessionZero datapack spec supported (semver).
  • dependencies: Optional. List of pack requirements by id with semver ranges. This supports cases where templates depend on datasets and datasets depend on other datasets. Import/activate must validate that all transitive dependencies are satisfied before enabling content.

5.3 Common Object Metadata

Objects within the datapack (datasets, templates) share a common set of identifying metadata.

{
  "id": "core-items",
  "name": "Core Items",
  "type": "dataset",
  "description": "A collection of basic weapons and armor.",
  "icon": "../media/images/core-items.png",
  "version": "1.0.0",
  "schemaVersion": "1.0.0"
}

5.4 Dataset Objects

Datasets are user-defined structured collections of data (e.g., a list of monsters, items, or spells).

{
  "id": "core-items",
  "type": "dataset",
  "datasetType": "items",
  "name": "Core Items",
  "description": "Weapons, armor, and consumables for the base ruleset.",
  "entries": {
    "sword": {
      "id": "sword",
      "name": "Sword",
      "description": "A basic weapon.",
      "icon": "../media/images/sword.png",
      "fields": {
        "damage": { "type": "number", "value": 10 },
        "weight": { "type": "number", "value": 3 },
        "rarity": { "type": "text", "value": "Common" }
      }
    },
    "potion": {
      "id": "potion",
      "name": "Healing Potion",
      "description": "Restores a small amount of HP.",
      "fields": {
        "healAmount": { "type": "number", "value": 20 },
        "consumable": { "type": "bool", "value": true }
      }
    }
  }
}

5.5 Character Templates

Character templates define the structure, fields, and default values for creating player or NPC characters.

{
  "id": "default-character",
  "type": "character-template",
  "name": "Generic Character",
  "description": "A base character layout usable across multiple systems.",
  "icon": "../media/images/character.png",
  "sections": [
    {
      "id": "core",
      "name": "Core Stats",
      "groups": [
        {
          "id": "attributes",
          "name": "Attributes",
          "fields": [
            { "id": "strength", "name": "Strength", "type": "number", "default": 10 },
            { "id": "dexterity", "name": "Dexterity", "type": "number", "default": 10 },
            { "id": "intelligence", "name": "Intelligence", "type": "number", "default": 10 }
          ]
        },
        {
          "id": "inventory",
          "name": "Inventory",
          "fields": [
            { 
              "id": "equipment", 
              "name": "Equipment", 
              "type": "list", 
              "datasetLink": { "datasetType": "items" } 
            }
          ]
        }
      ]
    }
  ]
}

5.6 Session Templates

Session templates are blueprints for setting up a campaign, including initial NPCs, rules toggles, and required datasets.

{
  "id": "basic-session",
  "type": "session-template",
  "name": "Basic Fantasy Campaign",
  "description": "A classic campaign setup with standard fantasy rules.",
  "icon": "../media/images/session.png",
  "characterTemplate": "default-character",
  "requiredDatasets": ["core-items"],
  "sections": [
    {
      "id": "session-info",
      "name": "Session Info",
      "groups": [
        {
          "id": "details",
          "name": "Details",
          "fields": [
            { "id": "setting", "name": "Setting", "type": "text", "default": "Thalindra" },
            { "id": "gmNotes", "name": "GM Notes", "type": "multi-line-text" }
          ]
        }
      ]
    }
  ]
}

5.7 Instances (Stored Separately)

Instances, such as a specific character or a running campaign's state, are typically stored outside of the core, reusable datapacks but follow a similar structure, referencing a template.

{
  "type": "character-instance",
  "templateId": "default-character",
  "name": "Aelric Stormhand",
  "fields": {
    "strength": 14,
    "dexterity": 11,
    "inventory": ["sword", "potion"]
  }
}

5.8 Validation and Schema Versioning

Formal, versioned JSON Schemas define the structure of szpack.json and core object types.

  • Each object declares a schemaVersion (global versioning per SessionZero release).
  • Validation tools confirm compliance before import/export.
  • Internal references (datasetLink, templateId, etc.) are resolved within the pack automatically.
  • External references are verified via dependencies in szpack.json.

Session Datapack vs Templates:

  • Session Template: A reusable blueprint for campaign/session setup. Lives under objects/session-templates/.
  • Session Datapack: The persisted, evolving state of an ongoing campaign. It is stored as a special pack and does not appear alongside normal content packs in the UI. Snapshots are versioned with timestamps. Export/import uses the same .szp format with a distinct type flag in szpack.json.

6. Architecture

6.1 High-Level Overview

SessionZero is split into three cooperating layers:

  • Client (Avalonia / .NET 9): The primary desktop application used by players and GMs. It is responsible for local data storage, datapack management, UI rendering, and establishing/maintaining real-time session connections. The client is offline-first and can run entirely without a backend.

  • Backend (ASP.NET Core Web API): An optional, self-hostable server that provides account management, persistent session storage, the SessionZeroDB (index of community datapacks), and signaling for P2P connections (WebRTC). Servers may be run privately or publicly and can optionally federate with other servers.

  • Federation Layer / SessionZeroDB: A network of self-hosted servers that optionally synchronize metadata (datapack manifests, public session listings, user profiles) between instances. Federation is opt-in per server and respects server-configured visibility and access controls.

6.2 Client Architecture (Avalonia)

Key responsibilities:

  • Local datastore and caching (SQLite for structured local data, filesystem for datapacks and media).
  • Datapack Manager: discovery, validation, import/export (.szp), and in-memory registry of loaded objects.
  • UI layer (MVVM pattern) using Avalonia controls and styles.
  • Networking components:
    • SignalR client for communicating with an ASP.NET backend.
    • WebRTC peer connection subsystem for direct P2P session data transfer (signaling via backend when needed).
  • Tools integration: a CLI helper (szpack) for building/extracting packs and optional pack signing/verification.

Runtime layout:

  • ViewModels: Represent datapacks, objects, sessions, and user state.
  • Services: DataPackService, StorageService (SQLite/File), NetworkingService (SignalR/WebRTC), AuthService, LoggingService.

6.3 Backend Architecture (ASP.NET Core)

Key responsibilities:

  • User account management (email/password auth, JWT tokens).
  • Session hosting and persistence (store session metadata and optional session snapshots in PostgreSQL).
  • SessionZeroDB: index and serve community datapacks and metadata; host uploaded .szp files on disk or object storage.
  • Signaling service for WebRTC: setup offers/answers and ICE candidate exchange to enable P2P connections between clients.
  • Federation endpoints for inter-server communication (signed JSON over HTTPS).

Components:

  • REST API controllers: Accounts, Sessions, Datapacks, Federation, Admin
  • SignalR Hubs: Real-time session coordination and lightweight session synchronization for clients that prefer server-mediated sync.
  • Storage: PostgreSQL for server metadata and user accounts; filesystem/object storage for datapack blobs; optional S3-compatible storage for large deployments.
  • Auth & Security: Password hashing (Argon2), JWT issuance and refresh, TLS for all endpoints, RBAC for admin operations.

6.4 Networking Model

  • Offline Mode: Client runs entirely locally; datapacks and session files live on the local filesystem / SQLite; no networking required.

  • LAN / P2P Mode: Clients can host sessions on a LAN. Discovery via mDNS/Zeroconf or optional UDP broadcast. For internet play, the backend's signaling service facilitates NAT traversal and WebRTC handshake. Actual session traffic (character updates, chat) is sent peer-to-peer where possible to minimize server load.

  • Server-Hosted Mode: For users who run or subscribe to an ASP.NET instance, sessions may be persisted on the server and clients can reconnect to continue campaigns. The server can optionally mediate real-time traffic for clients that cannot form direct P2P connections.

  • Federation: Servers exchange signed metadata (pack manifests, publicly shared pack indexes, optionally session discovery) on a scheduled or event-driven basis. Federation rules and visibility are configured by each server operator.

6.5 Data Flow Examples

Importing a Datapack (Client-only):

  1. User selects Import pack.szp.
  2. Client extracts the archive into the local datapacks directory.
  3. DataPackService validates szpack.json and object schemas and registers objects into the in-memory registry.
  4. The UI updates to show new templates and datasets.

Joining a Hosted Session (Server + P2P):

  1. Client authenticates to ASP.NET server via email/password, obtains JWT.
  2. Client requests to join a session; server verifies permissions and returns session metadata and peer list.
  3. Server provides WebRTC signaling data (or the client uses STUN/TURN if needed).
  4. Clients establish P2P channels and synchronize session state. Server stores session snapshots as needed.

6.6 Extensibility & Plugins

  • Design client services around interfaces to permit replacement or extension (e.g., IDataPackStore, INetworkingTransport).
  • Plugin API (Phase 3) will allow third-party modules to register new object types, UI panels, and data transformations while running within a sandboxed environment.

6.7 Deployment & Operations

  • Client: Distributed via platform-native packaging (AppImage/Flatpak for Linux, MSI for Windows). Continuous builds via GitHub Actions.
  • Server: Dockerized ASP.NET image with environment-driven configuration. Use PostgreSQL as the recommended production datastore and SQLite for small personal deployments.
  • SessionZeroDB: Each server can host its own repository; the official public index is recommended to be a well-maintained instance but is optional.

6.8 Session Model (Roles, Persistence, Snapshots)

  • Roles & Permissions: GM has write access to all session state; players can write to their own characters and any GM-granted scopes. Read access is constrained by GM settings (e.g., fog-of-war). Enforcement occurs client-side and, when connected, server-side or by the GM-authoritative peer in P2P mode.
  • Offline/Single-User Sessions: Operate with an implicit GM role. All features available without authentication.
  • Persistence: Ongoing campaigns are stored as Session Datapacks (see section 5.8). The backend can keep periodic snapshots (e.g., every N minutes or on significant events) to support recovery and reconnection.

6.9 Real-Time Sync Protocol (App-Level)

  • Transport: WebRTC DataChannel preferred; SignalR/WebSockets as fallback/mediated mode.
  • Envelope: { type, version, correlationId?, timestamp, payload } with monotonically increasing client logical clocks per entity.
  • Message Types: character.update, sheet.patch (JSON Patch/merge), chat.post, gm.command, session.snapshot, presence.update.
  • Ordering & Causality: Per-entity version vectors or lamport clocks to resolve last-write-wins where appropriate; GM-authoritative resolution for contested fields. Idempotent operations required.
  • Offline Reconciliation: Queue operations locally; on reconnect, diff against latest snapshot and apply conflict rules (prefer GM-authoritative state; surface conflicts to GM UI when ambiguous).
  • Versioning: Bump minor for additive messages; major for breaking changes. Clients include supported ranges in handshake.

6.10 Security & Privacy

  • Account lifecycle: Email verification, password reset via signed time-limited tokens, optional 2FA in future.
  • Rate limiting: Per-IP and per-account limits on auth, uploads, federation pulls.
  • Audit logging: Admin-scope access to server logs of sensitive actions (logins, uploads, deletions).
  • Secret management: Environment variables or vault-backed configuration; never commit secrets.
  • Data protection: TLS everywhere, Argon2 password hashing, JWT with refresh tokens and short-lived access tokens.

6.11 Federation Protocol (Minimal Spec)

  • Trust Model: Each server has a long-lived signing key (ed25519) and publishes its public key and metadata at /.well-known/sessionzero.
  • Request Signing: All federation HTTP requests include a detached signature header over method, path, timestamp, and body hash. Replay protection via timestamp and nonce cache.
  • Endpoints:
    • GET /federation/packs?page=... for manifest pagination
    • GET /federation/packs/{id} for pack manifest
    • GET /federation/nodes for discovery
  • Backoff & Pagination: Link-based pagination; clients respect Retry-After and exponential backoff on 429/5xx.
  • Visibility: Servers may export only public/indexable packs; private items never federate.

7. UI/UX Design

7.1 Philosophy

  • Desktop-first layout with responsive adjustments.
  • Blend of creative and functional design to support immersive TTRPG use.

7.2 Core Views

  • Dashboard
  • Datapack Manager
  • Data Editor (characters, templates, datasets)
  • Session View (GM & Player modes)
  • Chat/Log interface

7.3 Navigation & Key Workflows (MVP)

Navigation Map: Dashboard → (Datapack Manager | Data Editor | Sessions)

Key Flows:

  • Build Datapack: New Pack → Add Datasets/Templates → Validate (schema) → Export .szp
  • Start Offline Session: Create from Session Template → Play (implicit GM) → Auto-snapshot locally
  • Join Hosted Session: Auth → Select Session → Handshake (SignalR/WebRTC) → Sync state
  • Import Pack: File → Import .szp → Validate (schemas + dependencies) → Activate

8. Licensing

8.1 Software License

  • GNU Affero General Public License (AGPL-3.0): Ensures open-source continuity and attribution, prevents uncredited commercial rebranding.

8.2 User Content License

  • Creative Commons BY-SA 4.0: Allows sharing and adaptation with attribution.

9. Development Phases

Phase 1: Core Platform (MVP)

  • Client (UI, datapack editing, session management)
  • Backend (accounts, SessionZeroDB, P2P prep)
  • JSON datapack format implementation

Phase 2: Federation

  • Cross-server communication
  • Access controls and search indexing

Phase 3: Mobile and Plugins

  • Cross-platform mobile apps
  • Plugin and API extensibility

10. Testing & Quality

  • Unit Tests: Core services (DataPackService, StorageService, NetworkingService) with fixtures for characters/datasets/templates.
  • Schema Validation: CI job validates sample packs against JSON Schemas (see section 5.8) and rejects PRs with invalid packs.
  • Integration Tests: Import/export round-trips, dependency resolution, and session snapshot/recovery.
  • Compatibility Matrix: Validate on Windows and Linux for net9.0; browser target smoke tests where applicable.

11. Accessibility & Internationalization

  • Accessibility: Keyboard navigation across all primary views, sufficient color contrast, focus indicators, and screen-reader-friendly labels.
  • Internationalization: Resource-based localization for UI strings; UTF-8 throughout; prepare for RTL support; date/number formatting via invariant + locale-aware overlays.