Update website

This commit is contained in:
Chris Bell 2025-07-04 14:44:58 -05:00
parent eb337df174
commit 7b44e9146b
6 changed files with 1029 additions and 12 deletions

63
about-sessionzero.md Normal file
View File

@ -0,0 +1,63 @@
# SessionZero
So you want to run a tabletop RPG campaign? Awesome! But if you're like most people, you probably don't want to spend hours learning a complicated app or dealing with endless ads and in-app purchases. You just want a simple, powerful tool that lets you focus on the game, not the software. That's where **SessionZero** comes in.
## So, What's in the Bag of Holding?
**Works Offline, No Strings Attached** SessionZero works right in your browser and is built to be offline from the start. You can even hit "Install App" in your browser to use it like any other program on your computer or app on your phone.
**Build Your Own Universe** You're the architect. Create templates and content for any RPG you can imagine, from classic fantasy epics to your own homebrewed rules. You decide what a character sheet looks like and what it tracks.
**Characters, Not Spreadsheets** Go beyond basic stats. Track inventory, manage spell lists, keep detailed notes, and even add a private journal for all that juicy character drama. Link to your own custom lists of items or abilities to keep everything connected.
**Run Your Game, Your Way** By default, SessionZero is your private, offline tool. Want to run a live session online? You can with our optional service. Your players can always join with a free account. No need to pay for every player.
**A Library for Everything** Hoard all the things! Build, import, and share your own collections of spells, items, monsters, or whatever your game needs. Group them into "datasets" and load only the ones you need for your current campaign.
**Your Data is Yours. Period.** We believe your content belongs to you. Export your campaigns, characters, and creations as simple files you can actually read and edit. Share them with friends, back them up, or just keep them safe. No data prisons here.
## The Community Treasure Chest
SessionZero includes access to the **SessionZeroDB**, a free online library of datasets, templates, and more, all created by the community.
* **Downloading is always free for everyone** Even without an account. When online, SessionZero will even attempt to download or update required content for templates, making sure you stay up to date.
* **Uploading your own creations requires a paid account.** This helps us keep the lights on and the servers running for everybody.
Of course, you can always share your content with friends by just sending them the file directly.
## The Deal: What's Free vs. What's Paid
We want to be completely clear. SessionZero is free to use, and you can do a lot without ever paying a dime. But we also offer a paid subscription that helps support the project and gives you some extra perks. Here's the breakdown:
**FREE FOREVER (No Account Required):**
* The entire core app and all its features
* Complete offline functionality
* Creating content and building your own templates
* Managing characters and campaigns
* Downloading from the SessionZeroDB when online
**FREE ACCOUNT:**
* Everything above, plus:
* A public profile and friends' list
* Joining online games hosted by others
* Access to community forums and groups
* Ability to leave a rating or comment on content in the SessionZeroDB
* Access to the Adventurer's Guild and Adventurer role in our official discord server
**PAID SUBSCRIPTION:**
* Everything above, plus:
* Hosting live online sessions for your friends
* Uploading your creations to the SessionZeroDB
* Syncing your data across devices
* Priority support and early access to new features
* A cool shiny badge on your profile and access to the Game Master's Guild and Game Master role in our official discord server
## Who Is This For?
* Players who want total control over their character sheets and game data
* Game Masters who want to run any system whether it's a popular RPG, niche indie game, or their own homebrew content
* Anyone who's tired of apps that feel bloated, hard to learn, restrictive, or designed to constantly sell you something
## The Bottom Line
SessionZero is about freedom, flexibility, and respecting your game. It's not here to sell you a bunch of digital add-ons or lock your data in a vault. It's a tool built to help you play.

143
about.html Normal file
View File

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<title>About SessionZero</title>
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="d20_no-bg_medium.png">
</head>
<body>
<div class="page-container">
<header>
<nav>
<div class="nav-content">
<a href="index.html" class="logo-container">
<img src="d20_no-bg_medium.png" alt="SessionZero Logo" class="logo-placeholder">
<div class="logo-text">SessionZero</div>
</a>
<div class="nav-links">
<a href="about.html">About</a>
<a href="https://blog.sessionzero.app">Blog</a>
</div>
</div>
</nav>
</header>
<main>
<section class="hero">
<h1>About SessionZero</h1>
<p class="tagline">Everything you need to know about your new favorite TTRPG tool</p>
</section>
<section class="content">
<p>Tired of tabletop apps that box you in? SessionZero is your new best friend for any role-playing game. It's a free, flexible, and offline-first tool designed to help you run your game, your way. Forget about forced logins, surprise paywalls, or being locked into one company's universe. This is all about you, your friends, and your story.</p>
<h2>So, What's The Deal?</h2>
<div class="feature-detail">
<h3>Works Offline, No Strings Attached</h3>
<p>SessionZero works right in your browser and is built to be offline from the start. You can even hit "Install App" in your browser to use it like any other program on your computer or app on your phone.</p>
</div>
<div class="feature-detail">
<h3>Build Your Own Universe</h3>
<p>You're the architect. Create templates and content for any RPG you can imagine, from classic fantasy epics to your own homebrewed rules. You decide what a character sheet looks like and what it tracks.</p>
</div>
<div class="feature-detail">
<h3>Characters, Not Spreadsheets</h3>
<p>Go beyond basic stats. Track inventory, manage spell lists, keep detailed notes, and even add a private journal for all that juicy character drama. Link to your own custom lists of items or abilities to keep everything connected.</p>
</div>
<div class="feature-detail">
<h3>Run Your Game, Your Way</h3>
<p>By default, SessionZero is your private, offline tool. Want to run a live session online? You can with our optional service. Your players can always join with a free account. No need to pay for every player.</p>
</div>
<div class="feature-detail">
<h3>A Library for Everything</h3>
<p>Hoard all the things! Build, import, and share your own collections of spells, items, monsters, or whatever your game needs. Group them into "datasets" and load only the ones you need for your current campaign.</p>
</div>
<div class="feature-detail">
<h3>Your Data is Yours. Period.</h3>
<p>We believe your content belongs to you. Export your campaigns, characters, and creations as simple files you can actually read and edit. Share them with friends, back them up, or just keep them safe. No data prisons here.</p>
</div>
<h2>The Community Treasure Chest</h2>
<p>SessionZero includes access to the <strong>SessionZeroDB</strong>, a free online library of datasets, templates, and more, all created by the community.</p>
<ul>
<li><strong>Downloading is always free for everyone</strong> - even without an account. When online, SessionZero will even attempt to download or update required content for templates, making sure you stay up to date.</li>
<li><strong>Uploading your own creations requires a paid account.</strong> This helps us keep the lights on and the servers running for everybody.</li>
</ul>
<p>Of course, you can always share your content with friends by just sending them the file directly.</p>
<h2>The Deal: What's Free vs. What's Paid</h2>
<p>We want to be completely clear. <b>SessionZero is free to use, FOREVER</b>, and you can do a lot without ever paying a dime or even creating an account. But we also offer a paid subscription that helps support the project and gives you some extra perks. Here's the breakdown:</p>
<div class="pricing-tier">
<h3>FREE FOREVER (No Account Required)</h3>
<ul>
<li>The entire core app and all its features</li>
<li>Complete offline functionality</li>
<li>Creating content and building your own templates</li>
<li>Managing characters and campaigns</li>
<li>Downloading from the SessionZeroDB when online</li>
</ul>
</div>
<div class="pricing-tier">
<h3>FREE ACCOUNT</h3>
<p>Everything above, plus:</p>
<ul>
<li>A public profile and friends' list</li>
<li>Joining online games hosted by others</li>
<li>Access to community forums and groups</li>
<li>Ability to leave a rating or comment on content in the SessionZeroDB</li>
<li>Access to the Adventurer's Guild and Adventurer role in our official discord server</li>
</ul>
</div>
<div class="pricing-tier">
<h3>PAID SUBSCRIPTION</h3>
<p>Everything above, plus:</p>
<ul>
<li>Hosting live online sessions for your friends</li>
<li>Uploading your creations to the SessionZeroDB</li>
<li>Syncing your data across devices</li>
<li>Priority support and early access to new features</li>
<li>A cool shiny badge on your profile and access to the Game Master's Guild and Game Master role in our official discord server</li>
</ul>
</div>
<h2>Who Is This For?</h2>
<ul>
<li>Players who want total control over their character sheets and game data</li>
<li>Game Masters who want to run any system whether it's a popular RPG, niche indie game, or their own homebrew content</li>
<li>Anyone who's tired of apps that feel bloated, hard to learn, restrictive, or designed to constantly sell you something</li>
</ul>
<h2>The Bottom Line</h2>
<p>SessionZero is about freedom, flexibility, and respecting your game. It's not here to sell you a bunch of digital add-ons or lock your data in a vault. It's a tool built to help you play.</p>
<div class="cta-section">
<h3>Ready to Get Started?</h3>
<p><a href="https://web.sessionzero.app" class="cta-button">Open SessionZero</a></p>
<p class="cta-subtitle"><em>No account required. No installation needed. Just start playing.</em></p>
</div>
</section>
</main>
<footer>
<p>&copy; 2025 Bellsworne LLC. | Made with ❤️ by <a href="https://bellsworne.com/tech">Bellsworne Tech</a> | <a href="https://blog.sessionzero.app">Blog</a></p>
</footer>
</div>
</body>
</html>

274
design-doc.md Normal file
View File

@ -0,0 +1,274 @@
# Session Zero - Design Document
## 1. Core Philosophy
Session Zero is an application designed to help Game Masters (GMs) and players manage tabletop role-playing games (TTRPGs). The core idea is to provide a flexible, modular system where users can define their own game systems, create characters, and run sessions with integrated custom resources. The application is designed to be fully functional offline first by default. Optional online features, such as data synchronization and collaborative sessions, are available through a tiered account system to enhance the user experience.
## 2. Core Features
### 2.1. Library (Datasets)
- **Concept:** The Library is the foundational content repository. It allows users to create, edit, and delete individual pieces of information, such as spells, items, locations, lore entries, or rules.
- **Structure:** Each library entry is a standalone piece of data with a name and a set of key-value pairs (e.g., Item Name, Description, Cost, Weight).
- **Datasets:** The Library isn't monolithic. Users can group library entries into "Datasets" (e.g., "Core Fantasy Rules," "Sci-Fi Weapons Pack," "My Homebrew Monsters"). These datasets can be selectively loaded into game sessions.
- **Dataset Types:** The 'type' of a dataset is an arbitrary string that defines its purpose (e.g., "items," "spells," "monsters"). This allows for flexible categorization and retrieval of data. The application uses a few default dataset types, such as "items," "spells," "monsters," and "npcs" for specific functionality, but users can create custom types as needed.
- **Data Management:** Users can import and export their datasets as local files, allowing for easy backups and sharing outside of the application.
- **Online Library:** An online content library will be available for users to share and download Datasets and Templates. Downloading content is free for all users, but uploading requires a paid account.
### 2.2. Template Builder
- **Concept:** This feature allows users to define the structure of a character sheet for a specific game system.
- **Functionality:**
- **Core Fields:** Users can create a template by adding, naming, and ordering fields for the character's basic data (e.g., "Strength," "Dexterity," "Health Points"). Each field has a defined type (text, number, text area).
- Fields can be set as required or optional, and can have default values.
- Fields can also contain grouped data, such as a "Skills" section that contains multiple skill entries.
- **Custom Sections:** Users can define additional sections for the character sheet, such as a "Spells" or "Abilities" list. These sections can also link "Datasets" from the library, enabling features like searchable drop-downs to add items (e.g., spells from a "Magic" dataset) directly to the character sheet.
- **Outcome:** A saved template is used as the blueprint for creating new characters, complete with all its defined sections and data links.
### 2.3. Character Manager
- **Concept:** This is where users create and manage their characters based on the templates they've built.
- **Structure:** A character sheet will be composed of distinct sections:
- **Core Data:** A section for the character's core attributes and information as defined by the template's basic fields.
- **Inventory:** A dedicated section for managing items. The template can be configured to link this section to one or more "item" type datasets.
- **Journal:** A private, freeform notes section for players to track their character's personal story, thoughts, and important information.
- **Custom Sections:** Any additional sections defined in the character's template will appear here (e.g., a "Spells" section for a wizard).
- **Functionality:** Users can create new characters by selecting a template and filling in the data. They can view, edit, and delete existing characters.
### 2.4. Session Management
- **Concept:** A "Session" is the central hub for running a game. It brings together characters, rules, and notes for a specific adventure or campaign.
- **Structure:** Each Session will contain:
- A unique name/ID.
- **Loaded Datasets:** A list of active Datasets from the Library, making their content available within the session.
- **Session Notes:** A freeform text area for the GM to track events, plan encounters, etc.
- **Characters:** A list of characters participating in the session.
- **Online features:**
- **GM Mode:** The GM can control visibility of information, push updates to players, and manage session flow.
- **Player Mode:** Players can view their character sheets and receive updates from the GM.
- **Real-time Updates:** In the future, this will allow GMs to push updates to players' character sheets and session notes in real-time.
- **Chat Functionality:** A chat feature for GMs and players to communicate during the session.
- **Session History:** A log of actions taken during the session, such as character updates, notes added, and events triggered.
- **Chat Command Integration:** GMs and Players can use chat commands to trigger specific actions or updates within the session (e.g., rolling dice, updating character stats).
- **Modes of Interaction:**
- **Offline Mode (Default):** The user acts as both GM and Player. All updates are manual. Characters from the Character Manager can be manually added to a session.
- **Online Mode (Future):** This mode introduces distinct GM and Player roles, managed through an account system.
- **GM (Host):** Requires a paid account to host a session. The GM manages the session, controls information visibility, and pushes real-time updates.
- **Player (Participant):** Requires a free account to join a session hosted by a GM. Players can interact with their character sheet and receive live updates.
## 3. Monetization and User Accounts
### 3.1. Account Tiers
- **Guest (No Account):** This is the default state. The application is fully functional offline as a PWA. Guests can create and manage all local data, and download content from the online library, but cannot use other online features.
- **Free Account:** The primary benefit is the ability to join online sessions hosted by a paid user.
- **Paid Account:** Priced at approximately $5 USD/month, this tier provides full access to all online features, including:
- Hosting online sessions.
- Uploading content to the online library.
- Cross-device data synchronization.
- Access to other future perks.
## 4. Technical Stack
- **Client Application:** The application is built in C# and .NET Blazor as a standalone webassembly application, with PWA enabled for offline use.
- **Data Storage:** The application uses SQLite for local data storage, ensuring fast access and reliability. Data is stored in a structured format that allows for easy retrieval and manipulation.
- **Authentication Service:** Built using ASP web API, providing secure user account management and data synchronization.
## 5. Target Platforms
- **Desktop:** The primary platform, with a focus on Windows and Linux, with macOS support planned.
- **Mobile:** Future plans include adapting the application for mobile devices, allowing users to manage their games on the go.
## 6. Development Roadmap
1. **[Done]** Implement the Library for creating raw data entries.
2. **[Done]** Implement the Template Builder.
3. **[Done]** Implement the Character Manager.
4. **[Current]** Implement the initial `SessionsView` with basic note-taking.
5. Refine the `Session` model to be more robust. **First, we will focus on allowing "Datasets" from the Library to be loaded into a Session.**
6. Enhance Character Sheets with Inventory, Journal, and custom sections.
7. Integrate Characters into a Session.
8. Build out the GM/Player views within an offline session.
9. Implement local Dataset Import/Export.
10. UI/UX Polish Pass.
11. (Future) Implement User Account System (Guest, Free, Paid).
12. (Future) Develop Online Content Library (Download for all, Upload for Paid).
13. (Future) Explore and implement backend solutions for online collaboration (session hosting, data sync).
## 7. Technical Specifications
### 7.1. Data Validation
#### Basic Value Types
- All data in the system must conform to one of these value types:
- **Text**: Single-line string input
- **Text-Field**: Multi-line string input for longer content
- **Number**: Numeric values (integer or floating-point)
- **Boolean**: True/false values
- **Group**: Collection of nested key-value pairs
#### Validation Rules
- Each field must declare its type during creation
- All fields must have a non-empty name
- Names must be unique within their scope
- No null values are permitted
- Numbers must be valid integer or floating-point values
- Groups must contain at least one child entry
- Templates and datasets must validate their fields against these types
- Text fields have no length restriction by default, but specific implementations may impose limits
#### Type Coercion
- String to Number: Must be parseable as integer or float
- String to Boolean: "true"/"false" (case insensitive)
- Number to String: Standard string representation
- Boolean to String: Lowercase "true"/"false"
### 7.1.1 Dataset Entries
- Each entry consists of a string name and an associated value
- Value types are limited to:
- **Text**: Single-line text input
- **Text-Field**: Multi-line text input
- **Number**: Integer or floating-point values
- **Boolean**: True/false values
- **Group**: A collection of nested entries sharing a common purpose
- Example: A "Stats" group might contain entries for "Strength", "Dexterity", etc.
- Groups can be nested to create hierarchical data structures
- Entry Requirements:
- Names must be unique within their scope (either at root level or within a group)
- Groups must have at least one child entry
- Values must match their declared type
- Null values are not permitted
- Example Structure:
```json
{
"Name": "Longsword",
"Description": "A standard sword with a long blade",
"Stats": {
"Damage": "1d8",
"Weight": 3,
"IsMartial": true
}
}
```
### 7.2. Version Control
- Each dataset and template has a unique GUID identifier
- Version tracking uses semantic versioning (MAJOR.MINOR.PATCH)
- References to datasets/templates are dynamic:
- Characters load template data at runtime
- Sessions load dataset data at runtime
- This ensures compatibility across versions
### 7.3. Asset Management
- Supported assets:
- Character portraits
- Dataset entry images (items, monsters, etc.)
- Storage specifications:
- Local cache for offline use
- Remote storage for online library
- Size limits:
- Individual images: [suggest 2MB]
- Total cache size: [suggest 500MB]
- Format restrictions:
- Allowed formats: PNG, JPEG
- Maximum dimensions: [suggest 1024x1024]
### 7.4. Data Format
#### SZF (Session Zero Format)
- Primary format for all dataset files and templates
- Human-readable and easily editable
- Used for import/export operations
- File extension: `.szf`
##### Dataset Format Example
```szf
!type: dataset
!schema: 1.0.0
# Dataset Metadata
[Metadata]
Name (text) = Core Fantasy Items
Type (text) = items
Version (text) = 1.0.0
Description (text-field) = Basic fantasy items for any campaign
# First Entry (Longsword)
[Entry: Longsword]
Name (text) = Longsword
Description (text-field) = A standard sword with a long blade
Category (text) = Weapon
[Entry.Longsword.Stats]
Damage (text) = 1d8
Weight (number) = 3
IsMartial (bool) = true
# Second Entry (Health Potion)
[Entry: Health Potion]
Name (text) = Health Potion
Description (text-field) = Restores health when consumed
Category (text) = Consumable
[Entry.Health Potion.Properties]
HealingAmount (number) = 10
Consumable (bool) = true
```
##### Character Sheet Template Example
```szf
!type: character_template
!schema: 1.0.
# Template Metadata
[Metadata]
Name (text) = Fantasy Character Sheet
Version (text) = 1.0.0
Description (text-field) = A character sheet template for fantasy RPGs
# Dataset References
[Datasets]
## TODO: Declare datasets to be linked to this template somehow
# Core Info Section
[Section: Info]
Strength (number) = 10
Dexterity (number) = 10
Constitution (number) = 10
Intelligence (number) = 10
Wisdom (number) = 10
Charisma (number) = 10
# Inventory Section
[Section: Inventory]
[Section.Inventory.Items]
## This section will link to all "items" datasets bound to this template with drop-downs for adding to entries somehow
## and a value for how many
[Section.Inventory.Weapons]
## This section will link to all "weapons" datasets bound to this template with drop-downs for adding to entries somehow
## and a value for how many
# Journal Section
[Section: Journal]
Notes (text-field) = ""
# Custom Section for Spells
[Section: Spells]
SpellsList (group) = []
```
### 7.5. Dice System (Initial Implementation)
- Basic dice notation support (e.g., "2d6", "1d20")
- Simple modifiers (e.g., "1d20+5")
- Results displayed in chat when implemented
# UI Design Specifications
### Colors
- background-color: #1a202e
- primary-color: #3a4f6f
- primary-color-light: #4a5f7f
- secondary-color: #2d3f5c
- accent-color: #5b89b3
- text-color: #ffffff
- heading-color: #c5d5e6

View File

@ -1,4 +1,3 @@
<!DOCTYPE html>
<html lang="en">
<head>
@ -17,6 +16,10 @@
<img src="d20_no-bg_medium.png" alt="SessionZero Logo" class="logo-placeholder">
<div class="logo-text">SessionZero</div>
</a>
<div class="nav-links">
<a href="about.html">About</a>
<a href="https://blog.sessionzero.app">Blog</a>
</div>
</div>
</nav>
</header>
@ -25,32 +28,63 @@
<section class="hero">
<h1>SessionZero</h1>
<p class="tagline">A TTRPG companion that gets out of your way</p>
<a href="https://web.sessionzero.app">Open SessionZero</a>
<p style="margin-top:2rem; color:var(--neutral-medium); font-size:1.1rem;">
Tired of tabletop apps that box you in? SessionZero is your new best friend for any role-playing game. It's a free, flexible, and offline-first tool designed to help you run your game, your way. Forget about forced logins, surprise paywalls, or being locked into one company's universe. This is all about you, your friends, and your story.
</p>
<p>⚠️ SessionZero is still in development, but you can still access it while it's being developed! ⚠️</p>
<a href="https://web.sessionzero.app">Open SessionZero</a>
</section>
<section class="features">
<h2>Features</h2>
<h2>What's in the Bag of Holding?</h2>
<div class="feature-grid">
<div class="feature-card">
<h3>Characters</h3>
<p>Simple character system where you decide the details.</p>
<h3>Works Offline, No Strings Attached</h3>
<p>Built to be offline from the start. Install it like any other app on your computer or phone.<br>
<span style="color:var(--accent-color);">No internet? No problem!</span></p>
</div>
<div class="feature-card">
<h3>Sessions</h3>
<p>Manage your games and players online or at the table.</p>
<h3>Build Your Own Universe</h3>
<p>Create templates and content for any RPG you can imagine. You decide what a character sheet looks like.<br>
<span style="color:var(--accent-color);">You're the architect.</span></p>
</div>
<div class="feature-card">
<h3>System Agnostic</h3>
<p>You pick the rules and content, not us.</p>
<h3>Characters, Not Spreadsheets</h3>
<p>Track inventory, manage spell lists, keep notes, and add private journals for character drama.<br>
<span style="color:var(--accent-color);">Go beyond basic stats.</span></p>
</div>
<div class="feature-card">
<h3>Run Your Game, Your Way</h3>
<p>Private and offline by default. Want to run online? Use our optional service. Players join free.<br>
<span style="color:var(--accent-color);">No need to pay for every player.</span></p>
</div>
<div class="feature-card">
<h3>A Library for Everything</h3>
<p>Build, import, and share collections of spells, items, monsters, or whatever your game needs.<br>
<span style="color:var(--accent-color);">Hoard all the things!</span></p>
</div>
<div class="feature-card">
<h3>Your Data is Yours. Period.</h3>
<p>Export everything as simple files you can read and edit. Share, backup, or keep them safe.<br>
<span style="color:var(--accent-color);">No data prisons here.</span></p>
</div>
</div>
</section>
<section class="pricing-preview">
<h2>Free to Use, Built to Last</h2>
<div class="pricing-content">
<p>The entire core app is <strong>free forever</strong>. Use it offline, create content, build templates, manage characters, and download from our community library. Want to host online games or upload your creations? That's what our optional paid subscription is for.</p>
<p><a href="about.html" class="learn-more-link">Learn more about features and pricing →</a></p>
</div>
</section>
</main>
<footer>
<p>&copy; 2025 Bellsworne LLC. All rights reserved. | Made with ❤️ by <a href="https://bellsworne.com/tech">Bellsworne Tech</a></p>
<p>&copy; 2025 Bellsworne LLC. | Made with ❤️ by <a href="https://bellsworne.com/tech">Bellsworne Tech</a> | <a href="https://blog.sessionzero.app">Blog</a></p>
</footer>
</div>
</body>
</html>
</html>

View File

@ -51,7 +51,6 @@ header {
}
.nav-content {
max-width: 1200px;
margin: 0;
width: 100%;
}
@ -204,4 +203,211 @@ a:hover {
.logo-text {
font-size: 1.2rem;
}
}
/* Navigation improvements */
.nav-content {
margin: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-links {
display: flex;
gap: 2rem;
}
.nav-links a {
color: var(--text-color);
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease;
}
.nav-links a:hover {
color: var(--accent-color);
}
/* Pricing preview section */
.pricing-preview {
background-color: var(--form-background);
padding: 3rem 2rem;
border-radius: 8px;
margin: 2rem 0;
text-align: center;
}
.pricing-content {
max-width: 800px;
margin: 0 auto;
}
.pricing-content p {
font-size: 1.1rem;
line-height: 1.6;
margin-bottom: 1.5rem;
}
.learn-more-link {
display: inline-block;
background-color: var(--accent-color);
color: var(--button-text) !important;
padding: 0.75rem 1.5rem;
border-radius: 4px;
text-decoration: none;
font-weight: 500;
transition: background-color 0.2s ease;
}
.learn-more-link:hover {
background-color: var(--primary-color);
color: var(--button-text) !important;
}
/* About page specific styles */
.content {
max-width: 900px;
margin: 0 auto;
line-height: 1.6;
}
.content p {
margin-bottom: 1.5rem;
font-size: 1.1rem;
}
.content h2 {
color: var(--heading-color);
margin-top: 3rem;
margin-bottom: 1.5rem;
text-align: left;
}
.content h3 {
color: var(--heading-color);
margin-top: 2rem;
margin-bottom: 1rem;
}
.feature-detail {
background-color: var(--form-background);
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
}
.feature-detail h3 {
color: var(--accent-color);
margin-top: 0;
margin-bottom: 1rem;
}
.feature-detail p {
color: var(--neutral-light);
margin-bottom: 0;
}
.pricing-tier {
background-color: var(--form-background);
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
}
.pricing-tier h3 {
color: var(--accent-color);
margin-top: 0;
margin-bottom: 1rem;
border-bottom: 2px solid var(--accent-color);
padding-bottom: 0.5rem;
}
.pricing-tier ul {
list-style-type: none;
padding-left: 0;
}
.pricing-tier li {
padding: 0.5rem 0;
border-bottom: 1px solid var(--neutral-dark);
}
.pricing-tier li:last-child {
border-bottom: none;
}
.pricing-tier li::before {
content: "✓ ";
color: var(--accent-color);
font-weight: bold;
margin-right: 0.5rem;
}
.content ul {
margin-left: 1.5rem;
margin-bottom: 1.5rem;
}
.content li {
margin-bottom: 0.5rem;
line-height: 1.6;
}
.cta-section {
background-color: var(--primary-color);
padding: 3rem 2rem;
border-radius: 8px;
margin-top: 3rem;
text-align: center;
}
.cta-section h3 {
color: var(--text-color);
margin-top: 0;
margin-bottom: 1.5rem;
}
.cta-button {
display: inline-block;
background-color: var(--accent-color);
color: var(--button-text) !important;
padding: 1rem 2rem;
border-radius: 4px;
text-decoration: none;
font-weight: bold;
font-size: 1.1rem;
transition: background-color 0.2s ease;
}
.cta-button:hover {
background-color: var(--secondary-color);
color: var(--button-text) !important;
}
.cta-subtitle {
color: var(--neutral-light);
font-size: 0.9rem;
margin-top: 1rem;
}
/* Responsive navigation */
@media (max-width: 768px) {
.nav-content {
flex-direction: column;
gap: 1rem;
}
.nav-links {
gap: 1rem;
}
.pricing-preview {
padding: 2rem 1rem;
}
.feature-detail, .pricing-tier, .cta-section {
padding: 1.5rem;
}
}

297
szf-docs.md Normal file
View File

@ -0,0 +1,297 @@
# **Session Zero Format (.szf) Specification**
## **1. Overview**
The Session Zero Format (.szf) is a structured, human-readable data format for defining and storing tabletop RPG data, including characters, templates, and game assets. It is designed to be simple to write by hand, easy to parse, and flexible enough to support a wide variety of game systems.
### **Core Principles**
* **Human-Readable:** The format uses plain text and a clear, indented structure that is easy to read and edit.
* **Structured & Typed:** Data is organized into logical sections with explicitly declared field types defined in templates.
* **Extensible:** The format can be extended with new fields and sections without breaking existing parsers.
* **Portable:** .szf files are self-contained and can be easily shared and used across different platforms.
## **2. File Structure**
Every .szf file consists of three main parts: a **Header**, a **Metadata Section**, and one or more **Content Sections**.
### **2.1. Header**
The header is mandatory and must be the first two lines of the file. It declares the file type and the schema version.
```
!type: [file_type]
!schema: [schema_version]
```
* **\!type**: Defines the purpose of the file. Valid types are:
* dataset: A collection of related game elements (e.g., items, spells).
* character\_template: A blueprint defining the structure of a character sheet.
* character: An instance of a character created from a template.
* session: Data related to a specific game session (future use).
* **\!schema**: The version of the .szf specification the file adheres to (e.g., 1.1.0).
### **2.2. Sections**
Data is organized into named sections. Sections create a hierarchical structure for organizing related fields.
**Syntax:** `[SectionName]`
* SectionName must be a single word, is case-sensitive, and must use **PascalCase** (e.g., AbilityScores, CharacterInfo).
### **2.3. Nested Sections**
Sections can be nested to create a logical hierarchy. The dot (.) notation is used to define a parent-child relationship.
**Syntax:** `[ParentSection.ChildSection]`
This indicates that ChildSection is a subsection within ParentSection.
```
[AbilityScores]
Strength (number) = 10
[AbilityScores.Modifiers]
StrengthMod (calculated) = (AbilityScores.Strength - 10) / 2
```
### **2.4. Fields**
Fields represent individual pieces of data within a section. Each field has a name, a type, and a value.
**Syntax:** `FieldName (type) = value`
* **FieldName**: The name of the field. Must be a single word, is case-sensitive, and must use **PascalCase** (e.g., CharacterName, MaxHealth).
* **(type)**: The data type of the field, enclosed in parentheses. See Section 3 for a full list of types.
* **=**: The assignment operator.
* **value**: The data assigned to the field. The format of the value depends on the field type.
### **2.5. Comments**
Comments are denoted by a hash symbol (#) at the beginning of a line. Parsers should ignore comments. In-line comments are not supported yet.
```
# This is a full-line comment.
FieldName (text) = Some Value
```
## **3. Field Types**
The .szf format supports a variety of field types to handle different kinds of data. These types are declared in character_template and dataset files.
| Type | Description | Example Value |
|:---------------------|:----------------------------------------------------------------|:---------------------------------------------|
| text | A single line of text. | Elara the Brave |
| text-field | A multi-line block of text. | A long sword forged by...\nIt glows faintly. |
| number | An integer or floating-point number. | 16 or 3.5 |
| bool | A boolean value. | true or false |
| calculated | A value derived from a formula. | (Strength - 10) / 2 |
| system | A special field that controls application behavior. | |
| entry-reference | A reference to a single entry from a dataset. | ClassData or ItemData.Longsword |
| entry-reference-list | A comma-separated list of references to entries from a dataset. | CoreFeats.PowerAttack, CoreFeats.Cleave |
## **4. File Type Specifications**
### **4.1. Dataset (!type: dataset)**
A dataset file is a collection of structured entries.
* **[Metadata] Section**: Contains information about the dataset.
* Name (text): The human-readable name of the dataset.
* Type (text): The category of the dataset (e.g., items, spells, classes, etc.). This is a completely arbitrary value, and user-definable, but should match the intended use of the dataset.
* Guid (text): A globally unique identifier. **Optional**: If left blank, the system can generate one.
* Version (text): The semantic version of the dataset.
* **[EntryName]/Section**: In datasets, sections are referred to as entries. Each entry represents a specific item, spell, or other game element.
* EntryName is the unique key for the entry within the dataset.
* Every entry must have a non-empty `Name (text)` field. This is the display name for the entry.
**Example: CoreItems.szf**
```
!type: dataset
!schema: 1.1.0
# Metadata for the entire item collection
[Metadata]
# Required metadata for datasets
Name (text) = Core Fantasy Items
Type (text) = items
Guid (text) = c3d4e5f6-g7h8-9012-cdef-123456789012
Version (text) = 1.0.0
# Optional metadata
Author (text) = Fantasy Creator
Description (text-field) = A collection of basic items for any fantasy campaign.
# Definition for a Longsword
[Longsword]
Name (text) = Longsword
Description (text-field) = A standard sword with a long blade and crossguard.
Category (text) = Weapon
[Longsword.Stats]
Damage (text) = 1d8 slashing
Weight (number) = 3
Cost (number) = 15
IsMartial (bool) = true
```
### **4.2. Character Template (!type: character_template)**
A character_template defines the structure, fields, and rules for a character sheet.
* **[Metadata] Section**: Contains information about the template.
* **[RequiredDatasets] Section**: Lists all datasets required by this template.
* The field name is a local alias for the dataset (e.g., CoreItems).
* The value is a pipe-separated string: DatasetName|GUID|Version.
* **[SectionName]**: Defines a section on the character sheet. Contains fields with types and default values.
* Subsections can be defined using dot notation (e.g., `[AbilityScores.Modifiers]`).
* **System Fields**: Special fields that modify the behavior of sections.
* `DatasetType (system)`: Restricts a section to hold references from datasets of a specific type (e.g., `items`).
* `DatasetReference (system)`: Restricts a section to hold references from a specific dataset, identified by its alias from `[RequiredDatasets]`.
* `AllowQuantity (system)`: When set, allows entry-reference fields within that section to have an associated quantity field.
**Example: FantasyTemplate.szf**
```
!type: character_template
!schema: 1.1.0
[Metadata]
# Required metadata for character templates
Name (text) = Standard Fantasy Character
Guid (text) = f9e8d7c6-b5a4-3210-9876-543210fedcba
Version (text) = 2.1.0
# Optional metadata
Author (text) = Template Master
# Datasets needed for this character sheet
[Required Datasets]
ClassData (text) = Core Classes|aaa-bbb-ccc|1.5.0
ItemData (text) = Core Fantasy Items|c3d4e5f6-g7h8-9012-cdef-123456789012|1.0.0
WeaponData (text) = Core Weapons|12345678-90ab-cdef-1234567890ab|1.0.0
# Character information section
[Info]
CharacterName (text) =
# This field expects a single entry from the 'ClassData' dataset.
Class (entry-reference) = ClassData
# Ability scores with default values
[AbilityScores]
Strength (number) = 10
Dexterity (number) = 10
[AbilityScores.Modifiers]
StrengthMod (calculated) = (AbilityScores.Strength - 10) / 2
DexterityMod (calculated) = (AbilityScores.Dexterity - 10) / 2
# An equipment section linked to a specific dataset `WeaponData`
# This section can only contain references to entries in the `WeaponData` dataset.
[Equipment]
DatasetReference (system) = WeaponData
# An inventory section that can hold multiple items from the `ItemData` dataset.
[Inventory]
DatasetType (system) = items
AllowQuantity (system) = true
```
### **4.3. Character (!type: character)**
A character file is an instance of a character_template filled with specific data. It **only contains values**, as the structure and types are defined by the template.
* **[Metadata] Section**: Contains information about the character.
* TemplateRef (text): A mandatory reference to the source template: TemplateName|GUID|Version.
* **Content Sections**: The sections defined in the template are populated with the character's specific values. Field types are not re-declared.
**Example: Elara.szf**
```
!type: character
!schema: 1.1.0
[Metadata]
# Required metadata for character files
Name = Aela the Huntress
Guid = a1b2c3d4-e5f6-7890-abcd-ef1234567890
Version = 1.0.0
TemplateRef = Standard Fantasy Character|f9e8d7c6-b5a4-3210-9876-543210fedcba|2.1.0
[Info]
CharacterName = Aela the Huntress
# The value 'Ranger' is an entry from the 'ClassData' dataset,
# as specified by the 'Class' field in the template.
Class = Ranger
[AbilityScores]
Strength = 16
Dexterity = 14
# Calculated values are not stored in the character file.
[Equipment]
# This section becomes an addable list of items with quantities restricted to the `WeaponData` dataset, as defined in the template.
# 'PrimaryWeapon' is a user-defined field name for the item.
# The value 'Longsword' refers to the 'Longsword' entry in the 'WeaponData' dataset.
PrimaryWeapon = ItemData.Longsword
PrimaryWeapon.Quantity = 1
[Inventory]
# This section becomes an addable list of items from any dataset of type 'items', and allows specifying quantities.
# 'HealingPotion' and 'HempRope' are user-defined field names for the items,
# collected from the 'ItemData' notated by the prefix.
HealingPotion = ItemData.HealingPotion
HealingPotion.Quantity = 5
HempRope = ItemData.HempRope
HempRope.Quantity = 2
```
## **5. Advanced Features**
### **5.1. System Properties**
System properties are special fields within a character_template that modify the behavior of a section.
* `DatasetType (system) = type`: Restricts a section to holding references from datasets of a specific type (e.g., items).
* `DatasetReference (system) = alias`: Restricts a section to holding references from a specific dataset, identified by its alias from `[RequiredDatasets]`.
* **Note:** A section can have DatasetType or DatasetReference, but not both.
* `AllowQuantity (system) = true`: When set, allows entry-reference fields within that section to have an associated quantity field.
### **5.2. Quantity Fields**
If a template section has `AllowQuantity (system) = true`, a character file can specify a quantity for any item referenced in that section.
**Syntax:** `ReferenceFieldName.Quantity = value`
The quantity field's name is constructed by appending .Quantity to the name of the corresponding entry-reference field.
### **5.3. Calculated Fields**
Fields of type `calculated` contain formulas that are evaluated by the application.
* Formulas can reference other fields using dot notation to access other sections (e.g., AbilityScores.Strength).
* Supported operations should include basic arithmetic (+, -, *, /), and parentheses for grouping.
### **5.4. Wildcard Calculations**
For sections where AllowQuantity is enabled, special wildcard syntax can be used in calculated fields to perform aggregate calculations.
* `SectionName.*.FieldName`: Refers to the FieldName property of *all* items referenced in SectionName.
**Example (in a template):**
```
[Inventory]
DatasetType (system) = items
AllowQuantity (system) = true
TotalWeight (calculated) = Inventory.*.Weight * Inventory.*.Quantity
```
## **6. Best Practices**
1. **GUIDs:** Leave this blank, and the system will generate a GUID for you. This ensures uniqueness across datasets and templates.
If you need to specify one, use a valid GUID format.
2. **Versioning:** Use semantic versioning for your files to manage updates and breaking changes.
3. **Naming Convention:** Strictly use **PascalCase** for all SectionNames and FieldNames.
4. **Nested sections/Sub-sections:** Use dot notation to create logical hierarchies but avoid excessive nesting to maintain readability.
5. **Dependencies:** Explicitly list all required datasets in templates.
6. **Validation:** Before use, validate that a file's structure is correct and all references are valid.