update readme.md
This commit is contained in:
parent
8b5173153b
commit
8f2960dcab
302
readme.md
302
readme.md
@ -4,7 +4,7 @@
|
||||
|
||||
### 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.
|
||||
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
|
||||
|
||||
@ -17,8 +17,6 @@ The project will begin as a cross-platform desktop application (Windows and Linu
|
||||
* 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:
|
||||
@ -27,26 +25,22 @@ SessionZero consists of three main layers:
|
||||
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.
|
||||
@ -62,8 +56,6 @@ SessionZero consists of three main layers:
|
||||
* 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.
|
||||
@ -72,68 +64,222 @@ SessionZero consists of three main layers:
|
||||
* **Security:** Hashed passwords, secure token authentication.
|
||||
* **Data Portability:** All user data exportable in open formats.
|
||||
|
||||
---
|
||||
|
||||
## 5. Datapack Specification
|
||||
|
||||
### 5.1 Structure
|
||||
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 # Metadata
|
||||
├── szpack.json # Pack metadata and manifest
|
||||
├── media/
|
||||
│ └── images/ # Image assets
|
||||
│ └── images/ # Image assets (referenced by objects)
|
||||
└── objects/
|
||||
├── datasets/
|
||||
├── characters/
|
||||
├── character-templates/
|
||||
└── session-templates/
|
||||
├── datasets/ # User-defined structured data (e.g. items, NPCs)
|
||||
├── character-templates/ # Templates defining character structures
|
||||
└── session-templates/ # Templates defining session/campaign structures
|
||||
```
|
||||
|
||||
### 5.2 Metadata File (`szpack.json`)
|
||||
### 5.2 Pack Metadata (szpack.json)
|
||||
|
||||
Example:
|
||||
Each datapack contains a root metadata file that defines its identity, authorship, dependencies, and compatibility information.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "c9a3f9c8-8b8a-4f1f-9f3b-2d8c7f2c6c62",
|
||||
"name": "Example Pack",
|
||||
"version": "1.0",
|
||||
"version": "1.0.0",
|
||||
"author": "UserName",
|
||||
"license": "CC-BY-SA 4.0",
|
||||
"description": "A fantasy setting for SessionZero.",
|
||||
"created": "2025-10-15",
|
||||
"sessionzeroVersion": "1.0"
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 Object Format Example
|
||||
**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.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "character",
|
||||
"name": "Thalindra",
|
||||
"attributes": {
|
||||
"strength": 14,
|
||||
"intelligence": 12,
|
||||
"dexterity": 10
|
||||
},
|
||||
"image": "../media/images/thalindra.png"
|
||||
"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).
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
### 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.
|
||||
* **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.
|
||||
* **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.
|
||||
* **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)
|
||||
|
||||
@ -149,7 +295,7 @@ SessionZero is split into three cooperating layers:
|
||||
|
||||
**Runtime layout:**
|
||||
|
||||
* **ViewModels:** represent datapacks, objects, sessions, and user state.
|
||||
* **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)
|
||||
@ -206,6 +352,40 @@ SessionZero is split into three cooperating layers:
|
||||
* **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
|
||||
@ -221,19 +401,26 @@ SessionZero is split into three cooperating layers:
|
||||
* 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.
|
||||
* **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.
|
||||
|
||||
---
|
||||
* **Creative Commons BY-SA 4.0:** Allows sharing and adaptation with attribution.
|
||||
|
||||
## 9. Development Phases
|
||||
|
||||
@ -253,21 +440,14 @@ SessionZero is split into three cooperating layers:
|
||||
* Cross-platform mobile apps
|
||||
* Plugin and API extensibility
|
||||
|
||||
---
|
||||
## 10. Testing & Quality
|
||||
|
||||
## 10. Open Questions
|
||||
* **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.
|
||||
|
||||
1. Should we support local single-user mode without an account?
|
||||
2. How should dependency handling between datapacks work (e.g., one datapack relying on another)?
|
||||
3. Should we include an optional offline mode for play sessions without a backend?
|
||||
4. How should session persistence be handled for ongoing campaigns?
|
||||
## 11. Accessibility & Internationalization
|
||||
|
||||
---
|
||||
|
||||
## 11. Next Steps
|
||||
|
||||
1. Confirm open questions above.
|
||||
2. Create schema definitions for datapack object types.
|
||||
3. Design backend API endpoints.
|
||||
4. Create wireframes for client UI.
|
||||
5. Begin core MVP development (client + backend).
|
||||
* **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.
|
||||
Loading…
Reference in New Issue
Block a user