YAML Schemas
All content entities are defined in YAML files placed in the appropriate content/ subdirectory.
Location
Section titled “Location”Directory: content/locations/
id: tavernname: '@location.tavern.name'description: '@location.tavern.description'banner: tavern.pngmusic: tavern_ambience.oggambient: fire_crackling.ogg| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Display name (supports @key) |
description | string | Text shown at this location |
banner | string | Banner image filename |
music | string | Background music track |
ambient | string | Ambient sound loop |
Character
Section titled “Character”Directory: content/characters/
id: bartendername: '@character.bartender.name'biography: '@character.bartender.bio'portrait: bartender.pnglocation: taverndialogue: bartender_greetingstats: {}| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Display name (supports @key) |
biography | string | Character background text |
portrait | string | Portrait image filename |
location | string | Starting location ID |
dialogue | string | Dialogue ID for conversations |
stats | Record<string, unknown> | Extensible stats object |
Directory: content/items/
id: old_coinname: '@item.old_coin.name'description: '@item.old_coin.description'icon: old_coin_icon.pngimage: old_coin.pnglocation: inventorystats: {}| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Display name (supports @key) |
description | string | Full description |
icon | string | Small icon for inventory grid |
image | string | Large image for detail view |
location | string | Starting location: location ID, "inventory", or character ID |
stats | Record<string, unknown> | Extensible stats object |
Directory: content/maps/
id: townname: '@map.town.name'image: town_map.pngscale: 1locations: - id: tavern x: 200 y: 350 - id: market x: 500 y: 200| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Display name (supports @key) |
image | string | Map background image |
scale | number | Distance-to-travel-time multiplier |
locations | MapLocation[] | Location markers |
MapLocation
Section titled “MapLocation”| Field | Type | Description |
|---|---|---|
id | string | Location ID (must match a location entity) |
x | number | X coordinate on the map image |
y | number | Y coordinate on the map image |
Directory: content/quests/
id: odd_jobsname: '@quest.odd_jobs.name'description: '@quest.odd_jobs.description'stages: - id: started description: '@quest.odd_jobs.stage.started' - id: talked_to_merchant description: '@quest.odd_jobs.stage.talked_to_merchant' - id: complete description: '@quest.odd_jobs.stage.complete'| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Display name (supports @key) |
description | string | Quest description |
stages | QuestStage[] | Ordered list of quest stages |
QuestStage
Section titled “QuestStage”| Field | Type | Description |
|---|---|---|
id | string | Stage identifier (used with SET questStage) |
description | string | Text shown in journal for this stage |
JournalEntry
Section titled “JournalEntry”Directory: content/journal/
id: tavern_discoverytitle: '@journal.tavern_discovery.title'text: '@journal.tavern_discovery.text'category: places| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
title | string | Display title (supports @key) |
text | string | Entry content |
category | string | Category for grouping (e.g., "lore", "people", "places", "quest") |
Interlude
Section titled “Interlude”Directory: content/interludes/
id: chapter_onebackground: /assets/images/banners/dusk_road.jpgtext: | Chapter One: A New Beginning
The road behind you stretches long and empty. Ahead, the lights of town flicker through the evening mist.| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
background | string | Yes | Background image path |
text | string | Yes | Narrative text (supports @key) |
banner | string | No | Optional decorative frame/border image |
music | string | No | Music track to play |
voice | string | No | Narration audio file |
sounds | string[] | No | Ambient sounds to play |
scroll | boolean | No | Auto-scroll text (default: true) |
scrollSpeed | number | No | Auto-scroll speed in px/s (default: 30) |
triggerLocation | string | No | Location ID where this auto-triggers on enter |
triggerConditions | Condition[] | No | Conditions that must pass for auto-trigger |
effects | Effect[] | No | Effects applied when the interlude triggers (e.g. set a “seen” flag) |
Triggered via the INTERLUDE <id> DSL effect, or automatically when traveling to triggerLocation if all triggerConditions pass. See the Interludes guide.
GameConfig
Section titled “GameConfig”File: content/game.yaml
id: gamestartLocation: tavernstartTime: day: 1 hour: 8startFlags: {}startVariables: gold: 100 reputation: 0 _drinksBought: 0startInventory: []| Field | Type | Description |
|---|---|---|
id | string | Must be "game" |
startLocation | string | Starting location ID |
startTime | { day: number, hour: number } | Starting time |
startFlags | Record<string, boolean> | Initial flags |
startVariables | Record<string, number | string> | Initial variables |
startInventory | string[] | Item IDs the player starts with |
Locale
Section titled “Locale”Directory: content/locales/
Locale files are flat key-value dictionaries (not entities). They’re loaded by filename.
location.tavern.name: 'The Rusty Tankard'location.tavern.description: 'A cozy tavern with worn wooden tables.'character.bartender.name: 'Greta'bartender.greeting: 'Welcome! What can I do for you?'| Key | Value |
|---|---|
| Any string | Translated text |
Referenced with @key syntax in other content files. See Localization.