SessionZeroWasm/new-szf-docs.md

280 lines
11 KiB
Markdown

# **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 or after a field definition. Parsers should ignore comments.
```
# This is a full-line comment.
FieldName (text) = Some Value # This is an inline comment.
```
## **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).
* 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**: Defines a single item in the dataset.
* EntryName is the unique key for the entry within the dataset.
**Example: CoreItems.szf**
```
!type: dataset
!schema: 1.1.0
# Metadata for the entire item collection
[Metadata]
# These fields are mandatory for all datasets.
Name (text) = Core Fantasy Items
Type (text) = items
Guid (text) = c3d4e5f6-g7h8-9012-cdef-123456789012
Version (text) = 1.0.0
# Optional metadata fields
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.
**Example: FantasyTemplate.szf**
```
!type: character_template
!schema: 1.1.0
[Metadata]
Name (text) = Standard Fantasy Character
Guid (text) = f9e8d7c6-b5a4-3210-9876-543210fedcba
Version (text) = 2.1.0
Author (text) = Template Master
GameSystem (text) = Fantasy RPG Universal
# 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
# 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 dataset type
[Equipment]
DatasetType (system) = items # This section can hold references to any dataset of type 'items'
AllowQuantity (system) = true # Allows items in this section to have a quantity
# An inventory section that also allows quantities
[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]
Name = Elara the Brave
Guid = a1b2c3d4-e5f6-7890-abcd-ef1234567890
Version = 1.0.0
TemplateRef = Standard Fantasy Character|f9e8d7c6-b5a4-3210-9876-543210fedcba|2.1.0
[Info]
CharacterName = Elara
# 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]
# 'PrimaryWeapon' is a user-defined field name for the item.
# The value 'ItemData.Longsword' refers to the 'Longsword' entry in the 'ItemData' dataset.
PrimaryWeapon = ItemData.Longsword
PrimaryWeapon.Quantity = 1
[Inventory]
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 for nested values (e.g., AbilityScores.Strength).
* Supported operations should include basic arithmetic (+, -, *, /), parentheses for grouping, and common functions (e.g., FLOOR, CEILING, MAX, MIN).
### **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) = SUM(Inventory.*.Weight * Inventory.*.Quantity)
```
## **6. Best Practices**
1. **GUIDs:** Assign a persistent GUID to every dataset and template. Leave it blank during creation to have the system generate one for you.
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. **Organization:** Use nested sections to create a clear and intuitive data hierarchy.
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.