File Types & Schema Design
This project is built on a set of file types — structured data schemas that define what kinds of content exist and how they relate to each other. Understanding the file types is essential if you want to extend, modify, or build on this system.
The STA File Types
| File Type | Purpose | Designation |
|---|---|---|
| Character | Player characters and key NPCs | character |
| Species | Species definitions with bonuses and abilities | lore |
| Starship | Vessels with systems, departments, shields, hull | location |
| Equipment | Weapons, gear, devices, consumables | item |
| Location | Planets, starbases, stations, ship interiors | location |
| Mission | Adventures, scenes, objectives, rewards | event |
Schema Structure
Each file type has a schema — a JSON Schema definition that specifies which fields exist, their types, constraints, and relationships. The schema enforces data integrity: you can't write a number into a string field, and required fields must be present.
Built-In Fields
Every file type automatically includes these fields (do NOT add them to your schema):
- name (required) — The display name. Always present.
- description (optional) — Short blurb shown in cards.
- image (optional) — Cover image with focal point metadata.
Field Types
| Type | Use For |
|---|---|
string | Text, names, descriptions |
number | Numeric values (attributes, scores, costs) |
boolean | True/false flags |
enum | Fixed set of choices (use "enum" on string fields) |
object | Nested structures (attributes, systems) |
array | Lists of items (talents, inventory, scenes) |
image | Image fields with picker support |
Reference Fields
When a field points at another file, annotate it with referencedFileTypeSlug:
{
"species": {
"type": "string",
"referencedFileTypeSlug": "species"
}
}
When writing content, use the target file's slug as the value. The platform resolves slugs to durable reference IDs automatically.
Computed Fields
Values that can be derived from other fields should use expressions rather than being stored:
{
"stressMax": {
"type": "number",
"expression": "8 + ($self.attributes?.fitness ?? 7)"
}
}
Computed fields are read-only — they appear in reads but are rejected on writes. Change the inputs or the expression to affect the computed value.
File Type Design Principles
-
Store only what can't be derived. If a value can be calculated from other fields or referenced files, it should be a computed expression, not stored data.
-
Use collections, not numbered fields.
talents: []withmaxItems: 8, nevertalent1,talent2, etc. -
Reference, don't copy. If a Character has a Species, reference the Species file — don't duplicate species bonuses into the Character.
-
Define once, use everywhere. Reusable rules (skill definitions, talent effects, species traits) live on the type that owns them. Characters reference them; they don't copy them.
-
Stable keys, not display names. Use slug-based keys for maps and lookups. Display names are editable content, not identifiers.