Docs Reference

Contents

Document kinds

A game is documents. Every document says what it is in its kind and is checked against its JSON Schema in schemas/v1/. A file's name says its kind (driftwood.item.json is an Item), so tools, people and editors agree without opening it. Generated from the schemas.

Every document starts with the same five fields, left out of the tables below: kind; schemaVersion ("1.0"); id, which starts with its kind's prefix (arch.sentry, item.driftwood); name, for people; and meta: its description, status, provenance, notes and locks.

In a Game Pack (34)

GameManifest

game.json, at the pack's root
ids: a game id like game.tideline
schema: schemas/v1/game.schema.json

The game: game.json at the root of a pack. It pins a template, adds packs and kits, and names the documents the player boots with (theme, style, world, player, screens, input, camera). A reference left out is filled at bake with the only document of that kind, so a game on a template is playable before it names anything.

FieldTypeWhat it is
template requiredobjectThe template this game plays like (ADR-0006), from library/templates/.
packslist of objectLibrary packs this game adds: shared documents that use kits. Not supported by bake yet.
themea theme id like theme.drowned_coastWhat the game is about.
stylea style id like style.tidelineHow it looks and sounds.
languagea language code like en, fr or pt-BRThe language the game is written in. A Locale document carries it in another; the person picks one in the game's Options.
rootSeedintegerThe seed every other seed is derived from by name. Worlds, loot and brains all follow from it.
simobjectHow the simulation runs.
clockclock settingsHow the world clock runs, for a game with kit.clock: world minutes per real second, the hour a new game starts, and when dusk and dawn fall. Every field is optional; left out, the kit's defaults.
worlda world generator id like gen.tidelineThe world generator.
sceneslist of sceneThe places the game is played in, joined by doors: a wood and the den under it, a coast and the hold of the wreck on it. Each is a world of its own (kit.world_tiles), made the first time the player goes in. The game starts in the first, which is the game's world. A door (kit.core's door, on a usable) or the travel action takes the player to another, and what was taken, worked or downed in the one left stays as it was until the player comes back, in a save too. Leave it out for a game played in one place.
playerobjectWho the player is and where they start. Left out, the template's (its manifest.player).
flowobjectThe screens the game opens with. Left out, the template's (its manifest.flow).
menuobjectThe menu every game has: Esc, a pad's Start, the pause action or the touch controls' Pause opens it, and the game stands still until it closes. It offers Continue, Restart, Options (volume, text size, and screen shake and flashes when the game has them) and Save and quit, and the title (or the first page of a game with none) offers Continue while a save of the game is on the device. The player's own, drawn in the game's UI on kit.ui's ui.pause and ui.options Screens; a Screen of the game's with that id lays a page out instead, from the menu feed. Left out, all of it is on, in the engine's words. Set a part false only when the genre can't have it.
inputan input map id like input.action_survivalThe controls.
cameraa camera rig id like cam.orthoThe camera rig.
kitslist of a kit id like kit.melee: kit, a dot, then lowercase letters, digits and _Kits this game runs beyond its template's. Bake writes the full list here (template, game and what they require).
platformslist of "desktop" | "web"Where the game ships. The web is a first-class target.

GameBrief

brief.json, at the pack's root
ids: a brief id like brief.tideline
schema: schemas/v1/brief.schema.json

The game's brief: brief.json at the root of a pack. The first thing the Director proposes and the person approves: the pitch, the pillars every later choice is checked against, the core loop, and caps on scope. A design document: bake leaves it out of the bundle.

FieldTypeWhat it is
pitch requiredstringOne or two sentences: what the player does, and why it is fun.
pillarslist of stringThree to five short rules every later decision is checked against ("tactics beat stats").
templatea template id like tpl.action_survivalThe template the game fits.
coreLoopobjectWhat the player does over and over, in the vocabulary of kits.
scopeobjectCaps that keep the first version small.
checkpointslist of objectThe checkpoints the person has passed (docs/design/m2-director.md §4), each recorded by a decide tool when the person says so: c2 by mark_played once they have played the first playable. The Director never writes these; later stages' tools wait for them.
planplanThe way to a big ask, as milestones the person approves once (propose_plan): each a step a player can play, proven by its acceptance Playtests. complete_milestone marks one done when they pass; no other proposal may, and a done milestone stays as it was.

Ability

<folder>/<slug>.ability.json, in any folder of the pack
ids: an ability id like ability.dash
schema: schemas/v1/ability.schema.json

Something a body can do on demand, with a cooldown and maybe a cost: a dash, a fireball, a shield, a ground slam, a swipe. Any mover carries abilities with kit.core's abilities component (the player and anything a brain drives alike). The player uses one with its input action; any other body uses one by itself (auto, while when holds) or when a state machine or rule asks (use_ability). What it does is a list of actions, built from what the kits already do: put an Effect on itself or its target (apply_effect), fire a volley (kit.ranged's fire), dash (kit.move's dash), hit everything round it (kit.melee's blast), strike ahead in a platformer (platformer_strike), throw a blow or a shot through the body's own components (strike, shoot). ability.used, ability.refused and ability.ready tell rules, cues and views.

FieldTypeWhat it is
actionan input action id like use or dodgeThe InputMap action the player presses to use it. Only the player presses: any other body uses it by auto, or by use_ability from its state machine or a rule.
autobooleanA body other than the player uses it by itself as soon as it is ready and when holds: a turret's volley, a foe's charge.
whenboolean or an expression like self.health < 30It can only be used while this holds, with self the body using it: platformer_grounded(self) for a ground slam, self.health < 3 for a last stand. Left out, always.
cooldownMsnumberAfter a use, how long until it can be used again, in milliseconds (rounded to whole ticks).
costobjectA stat the use spends (mana, stamina): it can't be used with less, and using it takes this much.
do requiredlist of actionWhat a use does, in order, with self the body using it and target what it was used at (use_ability's at; a click's target for the player), which may be none.

Archetype

<folder>/<slug>.archetype.json, in any folder of the pack
ids: an archetype id like arch.sentry
schema: schemas/v1/archetype.schema.json

A kind of entity: the player, a machine, a campfire. Its tags, stats and components (from kits) say what it is and does; its model and cues say how it looks and sounds.

FieldTypeWhat it is
tagslist of a tag: lowercase letters, digits, - and _ (at most 32)Tags rules and expressions select by: has_tag(target, 'machine').
statslist of objectStarting values of stats declared in a Stats document. A stat left out starts at its declared default.
componentslist of componentWhat the entity can do, one component per kit feature: {"component": "melee", …its fields}.
modela model id like model.pineHow it looks.
cueslist of objectSounds this entity plays when events happen to it: an event that names it (self, entity, target...) plays its cue at it, and one that names its archetype in an arch field and no entity of it (an acorn collected, a crate moved on a grid) plays the cue at the listener. on "alive" plays a loop for as long as it lives (a hum).

Asset

<folder>/<slug>.asset.json, in any folder of the pack
ids: an asset id like asset.hero_run
schema: schemas/v1/asset.schema.json

A media file the person brought into the game, frozen: a picture (PNG, JPEG or WebP) or a sound (OGG Vorbis, WAV or MP3), kept in the pack under its content hash, with what its bytes are and where it came from. The person imports it (the Studio's Import, a file dropped on the Studio, or gamewright import); nothing else makes one, and the Director never writes one: it uses the person's assets by id, from a Sprite (sprite.sheet) or a Sound (sound.file). A changed file is a different asset: the hash pins the bytes, and a file that no longer matches it is refused. What the file is comes from its bytes, never its name, and must fit the player's limits. source is the ledger a store's AI disclosure is filled from, so say it exactly.

FieldTypeWhat it is
file requiredasset fileWhere the file is and the SHA-256 of its bytes. Import keeps it at assets/<name>-<the first 12 digits of its hash>.<format>, so a file is never overwritten by another: re-importing a changed file makes a new one, and undo finds the old one where it was.
bytes requiredintegerThe file's size in bytes. At most 6,000,000: the web Studio sends a file in one message, and the web player fetches every file before the game starts.
media requiredimage media or sound mediaWhat the file is, read from its bytes when it was imported: a picture's format and size, or a sound's format, length, channels and rate. The core reads them again from the file at every check and refuses a file that no longer says the same.
source requiredsourceWhere the file came from, in the person's own words: who made it, under what licence, from where, and whether AI made it. A store's AI disclosure (Steam's content survey, itch.io's AI tags) and a credits page are filled from these, so leave a field unstated rather than guess. Every file is made before the game ships, never while it plays.
originalNamestringThe file's name when it was imported (hero_run.png), so a person knows which of their files it is.

Biome

<folder>/<slug>.biome.json, in any folder of the pack
ids: a biome id like biome.coast
schema: schemas/v1/biome.schema.json

A kind of land: its grounds (how they walk and look), its props (what stands on it, and what taking them yields), and its water. Part of the world stamp.

FieldTypeWhat it is
grounds requiredlist of objectThe grounds a world is made of. Drawn flat (a topdown2d CameraRig), a later ground's edge spills over an earlier one's where they meet, so list them from the one that gives way to the one that wins.
propslist of objectWhat stands on the land. Props are not entities: they live in the world kit's tables with stable ids.
waterobject

BodyPlan

<folder>/<slug>.bodyplan.json, in any folder of the pack
ids: a body plan id like plan.quadruped
schema: schemas/v1/bodyplan.schema.json

A body plan and the motion presets written for it (docs/design/m6-presentation.md §7): the roles a rigged Model's joints can play (a quadruped's body, head, tail and four legs), and named gaits and poses (gallop, trot, jump, hurt) made of the same keyed moves a Model writes, by role instead of by joint. A Model names a plan, says which of its joints plays each role, and takes presets by name as its poses; its own moves then change any joint of any pose. The library's plans live in library/plans/, and a pack may hold its own (one with a library plan's id replaces it for that game). Bake carries every plan a game's Models use into its bundle. Looks only: no state hash reads it.

FieldTypeWhat it is
roles requiredlist of objectThe parts of this body a joint can play, each a pivot: a leg's role is the joint at the top of the leg, a head's the joint at the base of the neck. A Model maps each role to one of its joints; a role it leaves out goes to the joint of the same name, and its moves are left out when there is none.
sizeRoleslist of a slug: lowercase letters, digits and _, starting with a letter (at most 48)The roles whose joints' mean height above the ground is this body's size (a quadruped's four legs: its leg length). A Model's size over sizeM scales every forwardM and upM key, so a rabbit's bob is a rabbit's. None: shifts are not scaled.
sizeMnumberThe size the moves' forwardM and upM keys are written for, units (a fox's legs are about 0.42 long).
presets requiredlist of objectThe named poses this plan offers: gaits that loop (walk, trot, gallop, strut, flap) and one-shots (jump, fall, hurt). A Model takes one as a pose of the same name, or of the name it gives it.
moveslist of objectWhat each role does in each preset: a flat list, at most one move per role and preset, read exactly as a Model's moves are (kit.mesh's Move), with role in place of joint and preset in place of pose. A role no move of a preset names stays at rest in it.

CameraRig

<folder>/<slug>.camera.json, in any folder of the pack
ids: a camera rig id like cam.ortho
schema: schemas/v1/camera.schema.json

How the camera sees the game. ortho3d: a fixed yaw and pitch over an orthographic view that follows the player, snapped to texels so edges never crawl, with anything over the player stippled away. platformer2d: a flat side view of a 2D level (kit.platformer) at a whole-pixel scale, following the player and held inside the level; it reads viewHeightM (tiles of the level that fit the screen's height), followRate and snapTexels. topdown2d: a world (kit.world_tiles) drawn flat from above at a whole-pixel scale, its grounds autotiled and everything in it a sprite, for a game whose Style is flat_2d; it reads viewHeightM (tiles of the world that fit the screen's height), followRate and snapTexels.

FieldTypeWhat it is
rig required"ortho3d" | "platformer2d" | "topdown2d"
yawDegnumberTurn around the vertical axis; 45 looks along the diagonal.
pitchDegnumberTilt down from the horizon.
viewHeightMnumberHow many metres of the world fit the screen's height.
distanceMnumberHow far back the camera sits along its view (for clipping and fog, not size).
followRatenumberHow fast it catches up with the player, per second.
snapTexelsbooleanSnap to whole texels so edges never crawl.
occlusion"stipple" | "none"What happens to anything between the camera and the player.

Dialogue

<folder>/<slug>.dialogue.json, in any folder of the pack
ids: a dialogue id like dlg.harbour
schema: schemas/v1/dialogue.schema.json

A conversation, or a whole story, as a flat graph of lines and links (ADR-0003, L2), run by kit.core and started with the start_dialogue action. One line shows at a time: who says it and what they say. When the player advances, the line goes on to the first of its links without a choice whose when holds; with none, to the next line in the list, unless it is the last or says end, which ends the dialogue. Links with a choice are offered to the player once the line is read, and the one picked is taken. A line whose when does not hold is passed over as if it were advanced. Lines do actions as they are shown and links as they are taken, from the same vocabulary as rules: set_var keeps a flag a later line or link reads with when, end_game ends the game on an ending. Write the story top to bottom; give each branch's last line a link to where the branches meet again.

FieldTypeWhat it is
start requireda slug: lowercase letters, digits and _, starting with a letter (at most 48)The id of the line it starts on.
revealCpsnumberHow fast a line's words appear, in characters per second; 0 shows each line whole at once. Pressing advance while a line appears shows it whole; the next press goes on. Choices are offered once the line is whole.
speakerslist of objectWho speaks, by id: the name shown over their lines. A line with no speaker is narration.
lines requiredlist of objectEvery line, in reading order: a line goes on to the next one in this list unless a link from it says otherwise.
linkslist of objectWhere lines go other than the next line in the list: a jump (no choice), or a choice the player picks. Links from one line are tried in list order.

Effect

<folder>/<slug>.effect.json, in any folder of the pack
ids: an effect id like effect.slowed
schema: schemas/v1/effect.schema.json

A status a body can be under for a while: slowed, poisoned, shielded, hasted, stunned, invulnerable. Anything can put one on any entity (the apply_effect action, an ability, a hit that carries one, a foe's hitEffect) and take it off (remove_effect). While it lasts it changes what the kits that move and fight read, all in one place: how fast the body moves (kit.move, kit.platformer), how much harm it takes and deals (kit.melee, kit.ranged, kit.platformer), whether it can move or act at all (blows, dodges, shots, abilities, a foe's touch), and whether anything can hurt it. It can also run actions every so often while it lasts (regeneration, poison). It lives in the entity's state, so saves and replays carry it exactly; effect.started, effect.renewed and effect.ended tell rules, cues and views.

FieldTypeWhat it is
durationMsnumberHow long it lasts once put on, in milliseconds (rounded to whole ticks). 0 lasts until something takes it off.
stacking"refresh" | "extend" | "stack" | "keep"What putting it on again while it lasts does. refresh: it starts its time over. extend: its time is added to what is left. stack: one more stack, up to maxStacks, and its time starts over (every modifier counts once per stack). keep: nothing, the one already on stays as it is.
maxStacksintegerWith stacking stack: the most stacks it can have at once.
speedMulnumberMultiplies how fast the body moves of its own accord, per stack: 0.5 is a slow, 1.5 a haste. Knockback and dashes are not slowed.
damageTakenMulnumberMultiplies the harm that reaches the body, per stack: 0.5 a shield that halves blows, 2 a weakness. 0 shrugs every hit off (but the hit still lands: invulnerable turns it away).
damageDealtMulnumberMultiplies the harm the body does with blows, shots and strikes, per stack: 2 is a rage.
canMovebooleanfalse holds the body where it stands: no walking, running or jumping of its own (it still falls and is still knocked about). A stun, a root, a freeze.
canActbooleanfalse stops the body acting: no blows, dodges, shots or abilities, and a platformer foe that can't act does no harm to the touch. A stun or a silence.
invulnerablebooleantrue turns every hit away while it lasts: blows, shots, strikes and stomps do nothing, and a platformer player passes spikes and foes unharmed (a fall still counts).
everyMsnumberHow often the every actions run while it lasts, in milliseconds: the first time this long after it is put on.
everylist of actionActions run every everyMs while it lasts, once per stack, with self the body it is on and source whoever put it on: regeneration is add_stat on health, poison is kit.melee's damage on self.

GridRules

<folder>/<slug>.gridrules.json, in any folder of the pack
ids: a grid rules id like gridrules.sokoban
schema: schemas/v1/gridrules.schema.json

How a grid puzzle behaves (kit.grid_rules): PuzzleScript-style rewrite rules and win conditions, as flat lists. A rule is a row of pattern cells along a direction; its cells (with the rule's id as parent) say what each cell must hold (holds) and what it holds afterwards (becomes). Each turn: the avatar is marked to move, the rules that are not late run in list order, each until it changes nothing, then everything marked moves, then the late rules run the same way, then the win conditions are checked. Levels name the GridRules they play by.

FieldTypeWhat it is
ruleslist of ruleThe rules, in the order they run. Pushing is a rule too: with no rules the avatar only walks.
cellslist of pattern cellThe pattern cells of every rule, each naming its rule as parent and its place along the rule's direction with at (0 is where the pattern starts).
winlist of win conditionThe level is won after a turn in which every condition holds. With none, a level is never won.
passLimitintegerThe most passes one rule may make in one turn before it is stopped and the stop reported (a rule that keeps changing things forever). 200 is PuzzleScript's bound.

InputMap

<folder>/<slug>.input.json, in any folder of the pack
ids: an input map id like input.action_survival
schema: schemas/v1/input.schema.json

The game's controls: abstract actions (move, use, dodge) and the keys, mouse buttons and pad buttons bound to them. The simulation only ever sees actions, so bots, tours and replays drive the same game a person does.

FieldTypeWhat it is
actions requiredlist of object
pointerwhat the mouse, or a tap on the game, does in playThe pointer: a mouse, or a finger tapping the game's frame on a phone. The game hears it only in world terms the view works out: the point on the ground under it (on a grid of 1/64 m) and, on a click, the thing under it (an entity id, or prop:<prop id>), recorded in the input frame, so replays and Playtests repeat a pointer game exactly with no picture drawn. A mouse button presses an action as any key does (actions[].mouse). Menus and the game's Screens answer the mouse with or without it (hover chooses a row, a click takes it, a click on a key hint presses its key). Leave it out of a game the mouse doesn't play.

Item

<folder>/<slug>.item.json, in any folder of the pack
ids: an item id like item.driftwood
schema: schemas/v1/item.schema.json

A thing the player can carry: a material, a tool, food. How it is obtained (harvest, recipes, loot, starting kit) is checked statically, so an item nothing can produce is caught before anyone plays.

FieldTypeWhat it is
description requiredstringOne line the player reads.
bulknumberHow much of the carrying load one takes.
stackintegerHow many fit in one slot.
tagslist of a tag: lowercase letters, digits, - and _ (at most 32)
toolobjectSet when the item works as a tool: which verb it does (chop, dig, cut) and how hard a thing it can work.
useobjectSet when the person can use it from what they carry: eat it, drink it, light it, blow it. The carry app's confirm on its row uses one (kit.inventory: a use:<item id> press), spends a charge, takes one away once its charges are spent, and sends inventory.used, which a rule answers with what it does (add_stat health, show_message). Without a use, confirm puts it in hand.
modela model id like model.pineHow it looks when dropped or held.
iconasset refIts inventory icon: a PNG or WebP in the pack.

KitRequest

<folder>/<slug>.kitrequest.json, in any folder of the pack
ids: a kit request id like kitreq.hover_over_water
schema: schemas/v1/kitrequest.schema.json

A gap in the engine's vocabulary (ADR-0003 rule 4): something a game needs that no kit's components, actions, events, functions, passes or builders can say, filed by the Director instead of approximating it. It records the need, examples of use, the registration a kit would add, and the proposal that hit the gap. In the owner's workspace a coding agent can build it as a local kit; across games, the count of requests is the engine's roadmap signal. A design document: bake leaves it out of the bundle.

FieldTypeWhat it is
need requiredstringWhat the game needs and why the vocabulary can't say it, in the person's terms: what the player should see and feel, and what was tried.
examples requiredlist of stringHow games would use it: one situation per entry, in plain words or as a sketch of the document fields it would take.
proposed requiredobjectThe registration a kit would add, in the shape of kit.json, so a coding agent can start from it.
hitByobjectWhere the gap was found: the tool call and, when there was one, the proposal it was working on.

Level

<folder>/<slug>.level.json, in any folder of the pack
ids: a level id like level.first_push
schema: schemas/v1/level.schema.json

One level of a grid puzzle (kit.grid): its size, its cells as rows of characters, and a legend saying which objects each character places. Objects are archetypes with a grid_object component. Levels play in order, lowest first; bake proves each one solvable with the core's solver and stores the shortest solution as its witness.

FieldTypeWhat it is
orderintegerWhere the level comes in the game: lower plays first; levels with the same order go by id.
rulesa grid rules id like gridrules.sokobanThe GridRules this level plays by. Left out: the game's only GridRules document, or none (the avatar only walks).
sizeCells requiredlist of integer[width, height] in cells.
rows requiredgrid rows like 5#/#@o.#/5#: rows top to bottom split by /, where a number before a character repeats itThe cells, top row first. Each row expands to exactly width characters; 3# is ###. Digits and / are never legend characters.
legend requiredlist of legend entryWhat each character of rows places. Every character used must be here.
witnesswitnessWritten by bake, never by hand: the shortest solution the core's solver found, and what the search saw (difficulty signals).

Locale

<folder>/<slug>.locale.json, in any folder of the pack
ids: a locale id like locale.fr
schema: schemas/v1/locale.schema.json

The game in another language: every text a person reads, translated from the game's own language (the GameManifest's language). Each string replaces one text field, named by its key: the document's id, a colon, then the path to the field, its steps joined by '/', an array of things with ids stepped by the id and any other array by its index (dlg.elder:lines/hello/text, item.berries:name, rules.quest:rules/found/do/0/text, game.vale:menu/words/resume). A text the Locale leaves out shows in the game's own language. The person picks the language in the game's Options (the first time, their device's, when the game has it); it is presentation only, so saves, replays and the state hash never depend on it.

FieldTypeWhat it is
language requireda language code like en, fr or pt-BRAn ISO 639-1 language code, with a region where it matters (pt-BR).
strings requiredlist of objectEach text it translates: the key naming a text field of the game's documents, and the text in this language, keeping any {placeholder} its source has.
phraseslist of objectText a game works out as it plays rather than writes in a field: a HUD line a Screen's bind chooses ('Find the relic.' if var.quest == 1 else ''), or the verb a key strip shows (a usable's talk). Each source text, exactly as the bind gives it, and its translation; kit.ui shows the translation wherever the bound text is that source.

LootTable

<folder>/<slug>.loot.json, in any folder of the pack
ids: a loot table id like loot.sentry_scrap
schema: schemas/v1/loot.schema.json

What something drops: rolls picks from weighted entries. Weights may be expressions, so a drop can depend on the hour or the dropper.

FieldTypeWhat it is
entries requiredlist of object
rollsintegerHow many picks.

Model

<folder>/<slug>.model.json, in any folder of the pack
ids: a model id like model.pine
schema: schemas/v1/model.schema.json

A Tier 1 model recipe: a builder from a kit (mesh.tree, figure.machine …) and its parameters, the colours of its palette slots, and its draw budget. The player builds it at load, cached by the recipe's hash.

FieldTypeWhat it is
builder required"campfire.ring" | "driftwood.log" | "figure.person" | "machine.sentry" | "mesh.parts" | "rock.faceted" | "sound.file" | "sprite.baked" | "sprite.sheet" | "synth.bed" | "synth.layered" | "synth.sfx" | "tree.tiered" | "ui.theme" | "wreck.hull"A builder a kit registers that makes a mesh.
paramsvalueThe builder's fields: an object checked against the builder named in builder (vocab.schema.json, Builder<Id>Params). Left out, every field takes its default.
palettelist of objectThe colour of each of the builder's slots, usually a Style slot.
budgetobjectThe most it may cost to draw; the build fails past it.

PlatformLevel

<folder>/<slug>.plevel.json, in any folder of the pack
ids: a platform level id like plevel.meadow
schema: schemas/v1/plevel.schema.json

One level of a 2D platformer (kit.platformer): Rooms placed on a grid, by hand (rooms) or by the rooms.chain generator (generate), which lays a path of rooms from a start room in the top row to an exit room in the bottom row and fills the rest. Levels play in order, lowest first; touching the exit goes on to the next. Bake proves each level completable with the core's reachability search, which plays the player archetype's own movement numbers, and stores the path it found as the level's witness, which a Playtest replays in the engine.

FieldTypeWhat it is
orderintegerWhere the level comes in the game: lower plays first; levels with the same order go by id.
roomTiles requiredlist of integer[width, height] of every room in tiles; each placed Room must have this sizeTiles.
gridRooms requiredlist of integer[columns, rows] of the room grid. Row 0 is the top. A cell with no room is solid rock.
roomslist of placed roomRooms placed by hand, one per grid cell. With generate, leave it out: bake writes the rooms the generator placed.
generatepassLay the rooms out with a generator pass instead of placing them by hand: {"pass": "rooms.chain", "id": "<its name>", …fields}, seeded by this level's id and the pass id. rooms.chain is the only pass a PlatformLevel takes.
hazardDamagenumberHealth a spike or a fall out of the level takes before the player goes back to the last checkpoint.
looklevel lookThe colours the flat 2D view draws the level's tiles and sky in. Every field is optional.
witnesswitnessWritten by bake, never by hand: a path the core's reachability search played from the start to the exit, tick by tick, with the player archetype's movement numbers, and what the search saw.
chainchainWritten by bake for a generated level: the attempt that produced a completable level, and the path of rooms it laid, start first.

Playtest

<folder>/<slug>.playtest.json, in any folder of the pack
ids: a playtest id like test.stealth
schema: schemas/v1/playtest.schema.json

An acceptance scenario: a seed, a tour, a bot or the explorer, how long to run, what must hold at the end, the events it must reach, and metric thresholds. Every later change must keep it green.

FieldTypeWhat it is
seed requiredintegerUnsigned 32-bit seed. Child seeds are derived by name path (deriveSeed), never by draw order.
toura relative path inside the pack, like levels/forest.level.jsonA tour file in the pack that drives the player, like playtests/proof.tour.
localea language code like en, fr or pt-BRPlays it in this language, one of the game's Locales: its frames (L3) are drawn in it, so a translation is checked to fit and read as the game's own words are. Left out, the game's own language.
optionsa person's options for a game, as its Options page sets themPlays it as a person who set these on the game's Options page: its frames (L3) are drawn with them, so text grown to 200% must still fit and read, captions must read over the game, and a colour filter must keep things apart (with sees). Options change only what is drawn, so the run ends on the same state hash. Left out, the defaults every tool run draws.
seesa kind of colour blindness: protanopia (no red cones), deuteranopia (no green) or tritanopia (no blue)Draws its frames (L3) as a person with this colour blindness sees them (Machado et al. 2009, full severity), after any colour filter its options turn on: every subject must stand apart from the ground round it, and every text from what is behind it, by their eyes. A red foe on green grass that reads by hue alone collapses for deuteranopia, the most common kind. Left out, as everyone sees them.
stepslist of stringThe tour written inline, one command per item, for a Playtest without a tour file: the tour language of docs/design/m1-player.md §8 (seed 3, boot game, press confirm, wait 2, await game.end:win 20, shot hero with player). Give one of tour, steps, bot or explore.
bota slug: lowercase letters, digits and _, starting with a letter (at most 48)A bot that plays instead of a tour, one a kit of the game registers: kit.core's monkey presses the game's actions and walks at random (fuzzing), kit.core's seek works toward goals the way a person would, kit.melee's fight_tactics plays a fight.
exploretrueSearch the game instead of playing it once: the engine's explorer (Go-Explore) spends ticks going back to the states it found and acting from them at random, and reports every event it reached with a replay of the shortest way there. Red when it never reaches the win (whenever a rule can win the game) or an event in require. Give one of tour, steps, bot or explore.
ticks requiredintegerHow many simulation ticks to run; for explore, how many the explorer may spend in all.
runsintegerPlay it this many times: on its seed, then on seeds derived from it (deriveSeed(seed, "runs/1"), "runs/2"...), each a new game. A bot fuzzes this way ({bot: monkey, runs: 4, ticks: 3600}). Every run must end free of errors, broken invariants and failed asserts; an event in require needs one run to reach it.
skill"novice" | "casual" | "skilled" | "perfect"The hands of a bot that plays like a person (kit.platformer's playthrough): novice, casual (the default), skilled, or perfect (no reaction time, no timing error, no fumbles: it plays each level's witness exactly). Only with such a bot.
goalslist of a seek goal like make:rcp.campfire, reach:tarn or fightWhat the seek bot works toward, in order, by the obvious route and with a person's reaction time and fumbles: reach:<place>, near:<archetype id>, take:<prop kind>, have:<item id>, make:<recipe id>, make (the first thing a person would make: a recipe made by hand, needing a tool last, then the fewest items to come by; met at once in a game with no recipe), use:<item id> (comes by one if it carries none, as have:, then uses it as the carry app does: an Item with a use, eaten, drunk, lit), talk:<archetype id> (walks up to the nearest of them, uses it and reads its Dialogue to the end, taking the first choice on offer; talk alone: the nearest usable with a Dialogue), fight (the nearest foe), survive:<seconds> (stands until that many seconds of play have passed, or a win), win (waits for it). It works on the first goal not yet met, and is done when every goal is met; a goal may come twice (talk:arch.warden, have:item.bell, talk:arch.warden). With survive:<seconds>, the player downed or killed, or the game lost, before those seconds fails the goal being worked on and ends the run there; a lost game fails win.
assertlist of boolean or an expression like self.health < 30What must hold where the run ends, checked by the engine's own Expr VM: self (the player), game, var and tune, the built-ins and any kit function its kit.json marks pure, like var.fires_lit >= 1, item_count(self, 'item.scrap') >= 1 or platformer_done('plevel.meadow'). A function that may change the game is refused. Not with explore, which has no one end: its gate is require.
requirelist of an event id like crafting.made, or game.end:<outcome>Events the run must reach: an event id (crafting.made), or game.end:<outcome> (game.end:win). Checked in the trace of a tour or bot run (with runs, one run reaching it is enough), and against what the explorer reached.
metricslist of objectTrace metrics and the range they must fall in.

Recipe

<folder>/<slug>.recipe.json, in any folder of the pack
ids: a recipe id like rcp.campfire
schema: schemas/v1/recipe.schema.json

How to make something: what it consumes, what it makes or builds, where, with which tool and in how many world minutes.

FieldTypeWhat it is
stationan archetype id like arch.sentryThe archetype to stand at (a campfire, a bench). Left out, it is made by hand anywhere.
inputs requiredlist of item countWhat it consumes.
outputs requiredlist of item countWhat it makes. Empty when it only builds.
buildsan archetype id like arch.sentryAn archetype placed in front of the maker (a campfire).
timeMinnumberWorld minutes it takes.
toolobjectA tool the maker must carry: an item whose tool verb matches, with at least this hardness.

Room

<folder>/<slug>.room.json, in any folder of the pack
ids: a room id like room.meadow
schema: schemas/v1/room.schema.json

One room of a 2D platformer (kit.platformer): a screen of tiles written as rows of characters, and a legend saying what each character is: terrain (empty, solid, a one-way platform, a ladder, spikes), a thing to place (an archetype: a collectible, a checkpoint, the exit, an enemy) or the player's start. PlatformLevels place rooms on a grid, by hand or with the rooms.chain generator, which reads openSides and roles to build a path that is completable by construction; bake then proves it with the core's reachability search. Row 0 is the top of the room.

FieldTypeWhat it is
sizeTiles requiredlist of integer[width, height] in tiles. Every room of one PlatformLevel has that level's roomTiles.
rows requiredgrid rows like 5#/#@o.#/5#: rows top to bottom split by /, where a number before a character repeats itThe cells, top row first. Each row expands to exactly width characters; 3# is ###. Digits and / are never legend characters.
legend requiredlist of room legend entryWhat each character of rows is. Every character used must be here.
openSideslist of "left" | "right" | "up" | "down"The edges this room leaves open for a neighbour, which rooms.chain relies on when it lays a path through it: left and right openings are walked or jumped through, down is dropped through into the room below, up is dropped into from the room above. Keep openings where a neighbour's will meet them (left and right near the floor, up and down in the middle columns).
roleslist of "start" | "path" | "exit" | "filler"What rooms.chain may place this room as: start (the first room of the path; needs a start cell), path (a room the path passes through), exit (the last room; needs a thing whose platformer_touch role is exit) and filler (off the path). Left out, the room is never generated into a level and is only placed by hand.

RuleSet

<folder>/<slug>.rules.json, in any folder of the pack
ids: a rule set id like rules.fires
schema: schemas/v1/rules.schema.json

Event → where → do (ADR-0003, L2). When an event happens and where holds, the rule does its actions in order. Rules never wait; waiting belongs in a state machine.

FieldTypeWhat it is
rules requiredlist of object

Score

<folder>/<slug>.score.json, in any folder of the pack
ids: a score id like score.night_coast
schema: schemas/v1/score.schema.json

A game's music as a score kit.music renders at load (docs/design/m6-presentation.md §2): a key, a mode, a tempo and a meter; sections of whole bars, each with its chords; and stems, each voiced by a Sound (a synth.layered or synth.sfx recipe played at each note's pitch) and playing a generator or explicit notes. Every stem renders to exactly bars x beats per bar x 60 / tempo x rate samples and loops without a click. Stems play together; a layer turns stems up and down from the game (an expression over self, game, var and tune, eased per bar), and the first section whose when holds plays, switching on a bar line. Music only presents the game: it never changes it.

FieldTypeWhat it is
key requireda pitch class like C, F# or BbThe tonic: what scale degree 1 and chord I are.
mode required"major" | "minor" | "dorian" | "phrygian" | "lydian" | "mixolydian" | "locrian" | "harmonic_minor" | "pentatonic_major" | "pentatonic_minor"The scale degrees and chords are drawn from. minor is natural minor; the pentatonics keep melodies to five safe notes, and their chords come from major and minor.
tempo requiredintegerBeats a minute, the beat being the meter's lower number.
metera meter like 4/4, 3/4 or 6/8Beats a bar over the beat's note value.
rateintegerSamples a second every stem renders at. 22050 is plenty for synthesized music and bakes twice as fast as 44100.
seedintegerVaries what the generators choose (random arpeggios, humanized hits) without changing the score.
sections requiredlist of objectThe score's parts. At every bar line the first section whose when holds plays (a section without when always holds, so put the default last). A section loops until another takes over.
layerslist of objectVolumes stems follow: each a level from 0 (silent) to 1 (full), read from the game and eased toward over easeBars bars.
stems requiredlist of objectThe parts that play together: a bass, a pad, an arpeggio, drums. Each renders once per section it plays in.

Screen

<folder>/<slug>.screen.json, in any folder of the pack
ids: a screen id like ui.hud
schema: schemas/v1/screen.schema.json

A screen or HUD: a flat list of widgets placed by anchor and nested by parent id, bound to game state by expressions or fed by the UI's feeds. Drawn in whole multiples of the Style's pitch.

FieldTypeWhat it is
frame"slate" | "none" | "veil"slate draws the screen as an app on the slate tablet; none draws its widgets straight over the game; veil also dims the world behind the whole screen (the title).
openan input action id like use or dodgeThe input action that opens this app on the slate (carry, make).
verbstringWhat confirm does in this app, shown in the key strip (make, hold). The engine says use when it is left out.
widgets requiredlist of object

Sound

<folder>/<slug>.sound.json, in any folder of the pack
ids: a sound id like snd.hit
schema: schemas/v1/sound.schema.json

A Tier 1 sound recipe: a synth builder from a kit (synth.sfx, synth.layered, synth.bed) and its parameters, the mix category it plays in, its level, how many variants, and whether it loops. Baked to buffers at load.

FieldTypeWhat it is
builder required"campfire.ring" | "driftwood.log" | "figure.person" | "machine.sentry" | "mesh.parts" | "rock.faceted" | "sound.file" | "sprite.baked" | "sprite.sheet" | "synth.bed" | "synth.layered" | "synth.sfx" | "tree.tiered" | "ui.theme" | "wreck.hull"A builder a kit registers that makes a sound.
paramsvalueThe builder's fields: an object checked against the builder named in builder (vocab.schema.json, Builder<Id>Params). Left out, every field takes its default.
categorya slug: lowercase letters, digits and _, starting with a letter (at most 48)The mix-sheet row it plays in: bed, machine, event, step, ui, music (a Score's stems), or a row the Style adds.
levelDbnumberLevel relative to its category.
variantsintegerHow many takes to bake; each play picks one.
loopbooleanLoops seamlessly (synth.bed always loops).
captionstringWhat a person who can't hear it reads when they turn Captions on, in a few words: beast snorts, bell rings. Written without brackets (the player adds them). Caption the sounds that tell the player something they could miss, a warning above all; leave out their own steps and clicks. One-shots only: a loop or bed is never captioned.

Sprite

<folder>/<slug>.sprite.json, in any folder of the pack
ids: a sprite id like sprite.hero
schema: schemas/v1/sprite.schema.json

A Tier 1 sprite recipe: a builder that renders art for 2D games (sprite.baked renders a Model recipe from a fixed orthographic camera into pixel-art frames for named animations), its parameters, and the colours its palette snaps to. The player bakes it at load into one atlas with frame metadata, cached by the recipe's hash, so 2D games get their art from the same recipes as 3D ones. Archetypes show it through the sprite component.

FieldTypeWhat it is
builder required"campfire.ring" | "driftwood.log" | "figure.person" | "machine.sentry" | "mesh.parts" | "rock.faceted" | "sound.file" | "sprite.baked" | "sprite.sheet" | "synth.bed" | "synth.layered" | "synth.sfx" | "tree.tiered" | "ui.theme" | "wreck.hull"A builder a kit registers that makes an image or a tileset (sprite.baked).
paramsvalueThe builder's fields: an object checked against the builder named in builder (vocab.schema.json, Builder<Id>Params). Left out, every field takes its default.
palettelist of objectExtra colours every pixel may snap to, besides the shades of the model's own palette (an outline colour, a highlight the model lacks).

StateMachine

<folder>/<slug>.sm.json, in any folder of the pack
ids: a state machine id like sm.sentry
schema: schemas/v1/sm.schema.json

A brain as a flat list of states (ADR-0003, L2): patrol → notice → hunt → attack → forget. States may nest by parent id; a parent's transitions apply in all its children. A transition fires on an event, when a condition holds, or after some seconds in the state.

FieldTypeWhat it is
initial requireda slug: lowercase letters, digits and _, starting with a letter (at most 48)The state it starts in.
states requiredlist of object
transitionslist of object

Stats

<folder>/<slug>.stats.json, in any folder of the pack
ids: a stats id like stats.core
schema: schemas/v1/stats.schema.json

Declares the numbers entities carry (stats, read as self.health) and the game's variables (read as var.fires_lit). Expressions are checked against these names.

FieldTypeWhat it is
statslist of objectStats every entity may carry. An archetype gives each a base value; actions change it within min and max.
varslist of objectGame variables: one value each for the whole game, read as var.<id> and changed by actions.

Style

<folder>/<slug>.style.json, in any folder of the pack
ids: a style id like style.tideline
schema: schemas/v1/style.schema.json

How the game looks and sounds (ADR-0006): the render profile, the palette every @slot names, material families, sky and fog, the light budget, UI tokens, the audio mix and the juice (vfx). Only presentation reads it, so restyling a game is one document.

FieldTypeWhat it is
profile required"lit_ortho3d" | "flat_2d"The render profile that draws the game. lit_ortho3d: lit 3D under a fixed orthographic camera, in the Compatibility renderer (ADR-0007). flat_2d: the kits' own 2D views draw it (tiles from the side, a grid of cells, a world from above under a topdown2d CameraRig) and no 3D scene is built; the palette, UI tokens and audio mix apply as ever.
palettelist of objectNamed colours. Content refers to them as @slot (@bark, @turf), never by value. Some views also read slots by name (the flat grid view's backdrop, backdrop_top and backdrop_bottom): the vocabulary lists each view's palette.
materialslist of objectMaterials content can be made of. The family says how the profile lights it: made (land, wood, cloth: rough and matte, nothing quite straight), found (machine metal: panelled, ruled, with specular seams), water, foliage, emissive (gives light).
skyobjectLight and air through the day. Night is the moon colour with the night ambient.
lightsobjectPoint lights: how many the profile keeps lit at once (nearest first), and the warm and cold light colours.
uiobjectThe look of the UI.
audioobjectThe mix: category rows, the ambient beds, the sounds of events and the score.
vfxobjectJuice: what the game shows when something happens, drawn by kit.vfx. Each effect answers an event with particles where it happened, a flash or a squash on the entity it names, and a shake of the view. Effects are looks: they never change play, and the person can turn shake down and flashes off in the game's Options.

Theme

<folder>/<slug>.theme.json, in any folder of the pack
ids: a theme id like theme.drowned_coast
schema: schemas/v1/theme.schema.json

What the game is about (ADR-0006): its fiction, tone, what it never does, and how it names things. Mechanics never read it; the Director and generators do.

FieldTypeWhat it is
fiction requiredstringThe world in a paragraph: where, when, who, and what went wrong.
tonestringHow it feels, in a few words: quiet, tense, wry.
neverlist of stringThings this game never does or shows.
namingstringHow things are named: the words, sounds and patterns names use.

Timeline

<folder>/<slug>.timeline.json, in any folder of the pack
ids: a timeline id like tl.intro
schema: schemas/v1/timeline.schema.json

Things that happen one after another over time (ADR-0003, L2): a cutscene, a boss's phases, a gate that grinds open and then lets the wave in. Steps run in order in the simulation, counted in ticks and never by the clock on the wall, so a Timeline replays, saves and loads like the rest of the game. It starts on an event, as a rule does (on, where, once), with that event's self, target and fields, or from the start_timeline action, with the self it names. Each tick it does steps until one must wait: wait some seconds, until a condition holds (a boss's health under a threshold), say a line for as long as it takes to read, or move an entity there over some seconds. do runs actions at once (set_var, spawn, despawn, give, take, play_cue, set_state, face, start_timeline, end_game, any kit's action); camera points the views' camera at something or shakes it. A cutscene takes the player's control while it runs; a skippable one ends at once on the skip press, doing what is left of its actions and moves without waiting. Rules hear timeline.started and timeline.done.

FieldTypeWhat it is
onan event name like melee.hit or game.start: lowercase dotted wordsAn event that starts it, as a rule's on does: game.start, entity.spawned, melee.hit, a variable's own emit. Its steps read that event's fields (event.<field>), and its self and target when the event carries them. Left out, only the start_timeline action starts it. A Timeline already running for the same self is not started again.
whereboolean or an expression like self.health < 30It starts on its event only when this holds, read as a rule's where, with the event's self, target and fields: event.arch == 'arch.warden'.
oncebooleanIt runs at most once a game: once started, nothing starts it again. A cutscene seen once, a boss's phases.
cutscenebooleanThe player has no control while it runs: walking, using and fighting keys do nothing, and cutscene() is true, for a Screen that hides the HUD. The rest of the world goes on, so keep a cutscene to a quiet moment, or hold the dangerous ones still with set_state.
skippablebooleanA cutscene the player may end at once with the skip press (the InputMap's skip action, or confirm when it has none): the do steps left run and the moves left end where they were going, without waiting; lines, waits and camera steps are passed over. Only a cutscene is skipped.
steps requiredlist of stepWhat it does, in order. Each step's id is unique in the Timeline; a tour awaits timeline.step:<timeline id>/<step id> as a step begins.

Tuning

<folder>/<slug>.tuning.json, in any folder of the pack
ids: a tuning id like tune.combat
schema: schemas/v1/tuning.schema.json

Tuning knobs: named numbers with a range and a reason, read by expressions as tune.<id>. Bot sweeps turn them within their ranges; the reason says what the number is for, so nobody changes it blind.

FieldTypeWhat it is
knobs requiredlist of object

WorldGen

<folder>/<slug>.worldgen.json, in any folder of the pack
ids: a world generator id like gen.tideline
schema: schemas/v1/worldgen.schema.json

A world generator: a flat list of passes from kits (noise.height, scatter.props …), each with its own named seed stream, so adding a pass never moves another pass's output (ADR-0004). Editing it changes the world stamp, and old saves are refused by name.

FieldTypeWhat it is
sizeTiles requiredlist of integer[width, height] of the world in tiles.
chunkTilesintegerSide of a streamed chunk in tiles.
biome requireda biome id like biome.coastThe biome it builds.
passes requiredlist of passThe passes, each {"pass": "<kit pass>", "id": "<its name here>", "after": [ids], …fields}.

Made by the tools, or shipped with the engine (5)

Bundle

<pack>/.gamewright/build/<hash12>/bundle.json, written by bake
ids: a document id like item.iron_sword: a lowercase kind prefix, a dot, then lowercase letters, digits, _ and .
schema: schemas/v1/bundle.schema.json

bundle.json: the manifest of a baked game. The core writes it; the player checks it before loading anything (ADR-0002). content.json holds every resolved document; exprs.json the compiled expressions; media/ the files, named by content hash. id is the game's GameManifest id.

FieldTypeWhat it is
engine requiredobjectThe player versions that can run this bundle: min inclusive, below exclusive.
template requiredobject
kits requiredlist of objectEvery kit the game uses, with the version it was baked against.
content requiredfile ref
exprs requiredfile ref
documentCountinteger
media requiredlist of object
stamp requiredobjectThe world stamp (ADR-0004): a hash of what shapes generated worlds. A save made under another stamp is refused by name or migrated.
bakedBy requiredobject

ChangeSet

<pack>/.gamewright/changes/<id>.json, written by the Director's tools
ids: a change id like chg.20260930_sword_damage
schema: schemas/v1/changeset.schema.json

A proposed, reviewable change to a pack. Every tool that changes anything, whether driven by the agent or the user, produces one. Nothing touches the pack until it is approved. Operations carry the base hash of the file they change, so a proposal made against an older version is marked stale instead of overwriting newer work. Undo applies a new change set that is the inverse of an applied one; history is never rewritten. Change sets live in .gamewright/changes/ (and, when the project is a git repo, applied ones become commits). Unlike pack documents, a ChangeSet has its own lifecycle status instead of meta.status. Adapted from Reelwright's changeset.schema.json (MIT; see core/UPSTREAM.md).

FieldTypeWhat it is
title requiredstringOne line, imperative: 'Make the iron sword slower and stronger'.
rationale requiredstringWhy, in a few sentences: what was asked and how this answers it.
author requiredobject
createdAt requiredan RFC 3339 date-time like 2026-09-30T00:00:00Z
provenance requiredprovenanceWhere this document or asset came from. Required on everything, so the project can always answer who made this, with what, and under which license.
status required"proposed" | "approved" | "applied" | "rejected" | "reverted" | "stale" | "superseded"proposed: awaiting review. approved: accepted, not yet written. applied: written to the pack. rejected: declined by the person. reverted: undone by a later change set. stale: a base file changed since it was proposed. superseded: the agent replaced its own pending proposal with a newer one (supersededBy) before anyone decided it; it is history, not a decision.
historylist of object
toolobjectAgent or CLI tool that produced it.
baseobject
operations requiredlist of operation
previewslist of objectImages that show the change: screenshots, before/after pairs, diffs.
impactlist of objectWhat else the dependency graph says this change affects.
variationobjectSet when this is one of several alternatives ('give me 4 options'). Approving one rejects its siblings.
inverseOfa change id like chg.20260930_sword_damageThe applied change set this one undoes.
drafttrueThe person's own change held to the draft rule (docs.edit's draft, and the undo of the person's own changes): it may keep game-rule problems in the documents it writes, never a schema error there or a new problem in another document. Redo holds it to the same rule.
supersedesa change id like chg.20260930_sword_damageThe agent's earlier pending proposal this one replaces (the propose tools' replaces); that one is now superseded.
supersededBylist of a change id like chg.20260930_sword_damageSet when the status is superseded: the proposal that replaced this one (the options, when a variation group did).
afterlist of a change id like chg.20260930_sword_damagePending proposals this one builds on, in the order they apply: it was made and checked against the pack as it would be with them applied, and it can be approved only once they are. A base that is rejected or goes stale leaves this one stale.
createdDirslist of a relative path inside the pack, like levels/forest.level.jsonFolders that applying this change created, deepest last. Undoing it removes them again when they are empty.
diagnosticslist of objectValidation results for the proposed documents (warnings only; errors never reach a proposal).
verificationVerifyReport documentThe verification report for the pack as this change would leave it (docs/design/m2-director.md §5): L0 always; L1 and L2 when it touches simulation documents, with every Playtest re-run and compared with the pack before it. Written by the validators and the engine after proposal, never by the proposing tool.
costobjectWhat producing this proposal cost.

Kit

engine/addons/gamewright/kits/<kit>/kit.json, beside the kit's engine code
ids: a kit id like kit.melee: kit, a dot, then lowercase letters, digits and _
schema: schemas/v1/kit.schema.json

A kit's kit.json: the vocabulary a kit of engine code adds to Gamewright. The core generates vocab.schema.json and the Expr symbol table from every kit's registration, so documents, the Director's tools and the runtime always agree (ADR-0003). Written by engine developers, never by the Director.

FieldTypeWhat it is
version requireda semantic version like 1.2.0
description requiredstringWhat the kit makes possible and when to use it, written as a prompt for the Director.
requireslist of a kit id like kit.melee: kit, a dot, then lowercase letters, digits and _Kits this kit depends on. kit.core is always present and need not be listed.
systemslist of system declSimulation systems. The player orders them by after, provides and consumes; a cycle is an error.
viewslist of view declPresentation nodes (GwView) that draw the kit's state. Views never write to the simulation.
structslist of struct declNamed records that fields can use (type struct or list). Flat: a struct may use another struct by id, never itself, directly or through others.
componentslist of vocab declComponents an Archetype can carry. Each becomes a branch of the component union, discriminated by "component": "<id>".
actionslist of vocab declActions rules, state machines, dialogue and timelines can perform. Each becomes a branch of the action union, discriminated by "action": "<id>".
eventslist of event declEvents the kit emits, with their fields. Rules listen with on: "<id>"; Expr reads event.<field>.
functionslist of function declFunctions Expr can call. Pure: they read state and never change it.
passeslist of vocab declWorld generator passes a WorldGen document can list, discriminated by "pass": "<id>".
taskslist of vocab declBehavior tree tasks, discriminated by "task": "<id>".
builderslist of builder declTier 1 asset builders a Model, Sound or other recipe document can name, discriminated by "builder": "<id>". Versioned: a change to a builder's output is a new major.
tourVerbslist of tour verb declVerbs the kit adds to the tour language.
botslist of bot declBots the kit registers: drivers that play the player's part by input alone, named by a Playtest's bot and by the engine CLI's sim --bot.
saveKeyslist of a slug: lowercase letters, digits and _, starting with a letter (at most 48)Keys this kit's systems write into a save. Unique across all kits.

Template

library/templates/<name>/template.json, with the documents it supplies
ids: a template id like tpl.action_survival
schema: schemas/v1/template.schema.json

A genre template (ADR-0006): what a game plays like. It lives in library/templates/<name>/template.json, next to the default documents it supplies. A game pins one template by id and version; bake merges the template's documents with the game's, and a game document with the same id replaces the template's whole.

FieldTypeWhat it is
version requireda semantic version like 1.2.0This template's version. A change that alters how existing games play is a new major; games pin a major ("1") or an exact version.
useWhenlist of stringWhen a game fits this template, one situation per entry, so the Director can match a brief to it: "the player survives against a place and what hunts in it".
notForlist of stringWhat this template is the wrong start for, and what to pick instead.
kits requiredlist of a kit id like kit.melee: kit, a dot, then lowercase letters, digits and _The kits every game on this template runs. kit.core is always present. A game may add kits in its GameManifest.
defaultslist of a document id like item.iron_sword: a lowercase kind prefix, a dot, then lowercase letters, digits, _ and .Ids of the documents this template supplies (the files in its folder), so a game starts playable and replaces them one by one.
knobslist of a slug: lowercase letters, digits and _, starting with a letter (at most 48)Ids of the tuning knobs (in the template's Tuning documents) the Director may turn for a game on this template.
questionslist of objectWhat the Director must ask the person before making a game on this template.
manifestobjectWhat a game on this template starts with when its manifest (game.json) leaves it out: who the player is and where they start, the screens, the menu and the clock. Bake fills each missing field from here, so a game.json that only pins the template boots into play.
acceptancelist of objectWhat every game on this template must show when bots play it: the template's acceptance metrics.

VerifyReport

written by gamewright verify and on every proposal
schema: schemas/v1/verify.schema.json

What the verification ladder found (ARCHITECTURE §8): one report for a pack, or for a proposal as it would leave the pack. Rungs run in order and a rung runs only when the ones below it are green: L0 spec (schemas, semantics, static analysis), L1 boot (600 idle ticks twice, the same state, a clean log), L2 play (every Playtest, with metrics from its trace, engine invariants on every tick, and the explorer's reachability), L3 frames (named shots, with property checks and the readability of their subjects), and, only when asked for by name, L4 judge (a vision model asked grounded questions about L3's frames: where is the player, the threat, the goal; what is the player supposed to do) and L5 web (every Playtest tour in headless Chromium on the web export, ending on the native run's state hash); L4 judges L3's frames even when L3 is red. Every value comes from a validator or the engine, never from the agent. A proposal's report also compares every Playtest with the pack as it was, and a scenario that was green before and is red after is a regression, named first in the headline. A proposal that touches only presentation must leave every state hash as it was (restyle). The Director reads this, never raw logs.

FieldTypeWhat it is
ok requiredbooleanTrue when every rung that ran passed or had nothing to check, and nothing regressed.
headline requiredstringOne or two sentences for the model and the person. Regressions come first, as REGRESSION: …
gamea document id like item.iron_sword: a lowercase kind prefix, a dot, then lowercase letters, digits, _ and .The game's GameManifest id.
bundlebundle refThe baked bundle the engine ran.
changechange scopeThe proposal this report is for, and why these rungs ran.
restylerestyleWhat a presentation-only proposal proves (docs/design/m6-presentation.md §1): the simulation never reads a look, so L1's state hash and every L2 scenario's final state hash must equal the same runs' on the pack before it, bit for bit. Any difference turns that rung red with restyle.changed_play.
regressionslist of regressionScenarios that were green before the change and are red after it.
rungs requiredlist of rungThe rungs asked for, in order.
signalslist of stringSoft signals (research/testing-verification.md §5.2): worth a look, never a failure until calibrated.
engineGapslist of stringWhat the engine can't do yet that this report would have used, as contracts (an option, a result field).

Generated from schemas/v1/*.schema.json.