screens.json — file map
Optional defaults, then screen ids you choose — any names you need. title, pause, settings, and hud are common starters, not a closed list. Every screen uses the same shape (documented below under the example id title). Copy from examples/ and change labels first.
The whole file
Keys with { … } open below. Linked names jump to that section. Grey notes say what each key does. Under each section, Keys lists type, If omitted, allowed values, and a short note.
{
"defaults": { … }, // shared enter/exit fade for every screen that does not set its own
"title": { … }, // example id only — use any name (`pause`, `credits`, `gallery`, …); every screen uses this shape
"…": { … } // any other screen ids you invent — same shape
}
defaults
Shared enter/exit fade for every screen that does not set its own.
{
"defaults": { // shared enter/exit fade for every screen that does not set its own
"transition_in": "fade", // how screens appear
"transition_out": "fade", // how screens leave
"transition_duration": 0.3 // fade/slide length
}
}
Keys
transition_in enuminstantinstant · fade · slide_up · slide_down · slide_left · slide_righttransition_out enuminstantinstant · fade · slide_up · slide_down · slide_left · slide_righttransition_duration number00 = instant.Learn more: defaults
title
Example id only — use any name (pause, credits, gallery, …); every screen uses this shape.
{
"title": { // example id only — use any name (`pause`, `credits`, `gallery`, …); every screen uses this shape
"role": "modal", // how the screen sits in the world
"layers": [ { // ordered plates drawn bottom → top (required)
"type": "menu", // what this layer is
"order": 10, // draw order
"layout": {"host": "screen", "anchor_h": "center", "anchor_v": "center"}, // where the layer sits
"style": {"bg_color": "#101018"}, // look of this layer
"buttons": [ { // menu layer only — the button column
"label": "New Game", // caption
"label_key": "screen.title.new_game", // translated caption
"interaction": {"hooks": {"on_click": "new_game"}}, // what the button does
"show_if": "has_autosave", // when to show
"icon": "sprites/ico-pause.png" // optional glyph
} ],
"blocks": [ { // content layer only — rows inside the card
"type": "heading", // block kind
"bind": "bgm", // settings preference id
"label": "Music", // row caption
"text": "Audio", // copy for heading/text
"interaction": {"hooks": {"on_click": "close"}} // hooks for buttons/controls
} ],
"items": [ { // sprites layer only — UI pictures
"image": "ui/logo.png", // picture path
"interaction": {"hooks": {"on_click": "close"}} // click / hover hooks
} ],
"interaction": {"hooks": {"on_click": "close"}}, // layer hooks (background / chrome)
"modulate": "#ffffff", // layer tint
"scale": 1.0 // layer scale
} ],
"pauses_tree": false, // pause the game while open
"transition_in": "fade", // this screen's enter
"transition_out": "fade", // this screen's exit
"transition_duration": 0.3, // this screen's fade length
"interaction": {}, // screen-level hooks
"shader": {}, // screen shader
"action_context": "", // hook allowlist context
"modulate": "#ffffff", // whole-screen tint
"scale": 1.0, // whole-screen scale
"plane": "", // draw plane override
"persistent": false, // stay when others stack
"input_passthrough": false // clicks pass empty areas
}
}
Keys
role enummodalmodal · hud · scenemodal = full menu (default). hud = stays up during play. scene = under characters.layers[].type enumbackground · menu · content · sprites · chromebackground plate · menu button column · content card of blocks · sprites UI pictures · chrome extra controls (e.g. Close).layers[].order numberlayers[].layout objecthost: screen or panel (dock to dialogue box).layers[].style objectsource pack compose.layers[].buttons[].label stringlabel_key when translating.layers[].buttons[].label_key stringlabellayers[].buttons[].interaction objecthooks.on_click is a verb string (new_game, close, screen:pause), a command object, or an array of those.layers[].buttons[].show_if stringhas_autosave for Continue).layers[].buttons[].icon pathlayers[].blocks[].type enumbind is setheading · text · separator · link · spacer · image · button · button_row · slider · toggle · history · save_slots · scroll · tabletype when using preference bind instead. Common: heading, bind (as field), history, save_slots.layers[].blocks[].bind stringmaster · bgm · sfx · typing_enabled · typing_speed_scale · auto_advance_default · locale · …type when bind is set.layers[].blocks[].label stringbind, builds a settings row (label | control).layers[].blocks[].text stringtext_key or nonetext / heading body. text accepts BBCode.layers[].blocks[].interaction objectlayers[].items[].image pathkind: image sprites.layers[].items[].interaction objectlayers[].interaction objecton_click: close for click-outside. Chrome uses the same hook shape.layers[].modulate colorlayers[].scale number1[x,y]).pauses_tree boolfalsetrue · falsepause). HUD screens never pause.transition_in enumdefaultsinstant · fade · slide_up · slide_down · slide_left · slide_rightdefaults.transition_in for this screen only.transition_out enumdefaultsinstant · fade · slide_up · slide_down · slide_left · slide_rightdefaults.transition_out.transition_duration numberdefaultsdefaults.transition_duration.interaction objectshader objectaction_context stringmodulate colorscale number1plane stringrolerole.persistent boolrole (hud is persistent)input_passthrough boolrole (hud passes through)Learn more: title