Skip to content

YAML Schemas

A schema describes the fields a file can contain and which ones are required. An entity is one structured piece of game content, such as a location, character, or quest. Define each entity in a YAML file in the matching content/ subdirectory.

Every entity has an id. Ids must be unique within their type: two location files cannot both be id: town, and validation reports the clash with both file names. Different types may reuse an id (a location and an item can both be called key).

Directory: content/locations/

id: tavern
name: '@location.tavern.name'
description: '@location.tavern.description'
banner: tavern.png
music: tavern_ambience.ogg
ambient: 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 filename
ambient string Ambient sound filename

Directory: content/characters/

id: bartender
name: '@character.bartender.name'
title: '@character.bartender.title'
biography: '@character.bartender.bio'
portrait: bartender.png
location: tavern
dialogue: bartender_greeting
stats:
strength:
name: '@stat.strength'
value: 16.2
class:
name: '@stat.class'
value: '@class.ranger'
Field Type Description
id string Unique identifier
name string Display name (supports @key)
title string Optional title (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, CharacterStat> Numeric or string character traits

Each stat has a stable key, a player-facing name, and a numeric or string value. Both the name and a string value support @key localization. Decimal numbers are valid. Prefix a stat key with _ to keep it off the built-in character sheet while retaining it for conditions, effects, and text interpolation.

The shorter strength: 16 form is also accepted. Its key becomes the display name.

File: content/player.yaml

The player is defined separately from NPCs. It does not have a location, dialogue, relationship, or party-membership field.

For a profile supplied by the game:

name: '@player.name'
title: '@player.title'
biography: '@player.biography'
portrait: hero.png
stats:
strength:
name: '@stat.strength'
value: 16

The same file can provide the replaceable profile text used by the project template:

name: '@player.name'
title: ''
biography: ''
portrait: ''
stats:
class:
name: '@stat.class'
value: '@class.ranger'
Field Type Description
name string Optional fixed name (supports @key)
title string Optional fixed title (supports @key)
biography string Optional fixed biography (supports @key)
portrait string Optional fixed portrait filename
stats Record<string, CharacterStat> Stats defined by the game

The profile mode is selected by playerCreatesProfile in content/game.yaml. When it is true, the built-in renderer asks for a name, title, and biography; only the name is required. Those entered values replace the corresponding profile text. The modal does not provide portrait uploads. When the flag is false, the profile fields from player.yaml are used directly. Stats always come from player.yaml.

Directory: content/items/

id: old_coin
name: '@item.old_coin.name'
description: '@item.old_coin.description'
icon: old_coin_icon.png
image: old_coin.png
location: inventory
stats: {}
Field Type Description
id string Unique identifier
name string Display name (supports @key)
description string Full description
icon string Small icon filename
image string Large image filename
location string Starting location: location ID, "inventory", or character ID
stats Record<string, unknown> Stats for game-specific data

Directory: content/maps/

id: town
name: '@map.town.name'
image: town_map.png
scale: 1
locations:
- 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 filename
scale number Pixels per hour of travel. Must be greater than zero. Higher values mean faster travel.
locations MapLocation[] Location markers
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

A game can contain multiple maps. At runtime, the engine shows the map that contains the player’s current location. Validation rejects maps that reference missing locations or put the same location on multiple maps.

Directory: content/quests/

id: odd_jobs
name: '@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
completesQuest: true
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
Field Type Description
id string Stage identifier (used with SET questStage)
description string Text shown in journal for this stage
completesQuest boolean Optional; marks this as a finishing stage

Directory: content/journal/

id: tavern_discovery
title: '@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")

Directory: content/interludes/

id: chapter_one
background: dusk_road.jpg
text: |
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 No Optional background image filename
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.

File: content/game.yaml

title: My Game
subtitle: A text-based adventure
author: North Road Studio
playerCreatesProfile: true
startLocation: tavern
startTime:
day: 1
hour: 8
startFlags: {}
startVariables:
gold: 100
reputation: 0
_drinksBought: 0
startInventory: []
Field Type Description
title string Player-facing game title
subtitle? string Optional line beneath the title
author? string Author or studio shown above the title when no title logo is set
playerCreatesProfile boolean Ask the player for profile text in the built-in renderer
shell? ShellConfig Shell screen configuration
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

playerCreatesProfile defaults to false. It controls how the player profile is initialized. The profile content and starting stats remain in content/player.yaml.

Directory: content/locales/

Locale files contain localization keys and their translated text. The filename sets the locale code.

content/locales/en.yaml
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.