Shared shapes
Some settings look the same wherever they appear; others share only a name. Each shape below is tagged:
- shared — one shape, one meaning, everywhere.
- per-surface — same name, different body. The table says which surface accepts what.
| Shape | Tag |
|---|---|
| Fades and slides | Shared vocabulary |
| Pictures (texture specs) | Per-surface |
| Position on screen | Per-surface (host varies) |
| Conditions and “only when” | Split — three different shapes |
Sticky vs this moment (apply) | Shared |
Live links to flags (bind) | Shared (surface list varies) |
| Click, hover, focus (hooks) | Shared vocabulary, per-surface events |
Looks per state (state_visual) | Shared |
| Layering one look on another | Shared |
| Effects (shaders) | Per-surface |
modulate and shader_params | Per-surface |
Fades and slides
Shared vocabulary. Kinds: instant, fade, slide_up / down / left / right.
| Field | Meaning |
|---|---|
transition | Same kind for enter and leave |
transition_in / transition_out | Separate enter / leave |
duration / transition_duration | Seconds (0 = instant) |
Used on backgrounds, characters, sprites, objects, panels, screens. The default differs by surface (e.g. bg fades by default; char is instant), so check the command page.
One exception: char_layout accepts only "" / instant / fade (no slides).
→ Transitions · character expression swaps: Expression fades
Pictures (texture specs)
Per-surface. Two shapes share the word “picture”:
Chrome faces — panel plates, buttons, choice faces, text-input fields, sliders:
| Form | Meaning |
|---|---|
| string path | Still picture in the project |
{ "file", "modulate"? } | Still + optional tint |
{ "frames", "fps"?, "modulate"? } | Flipbook |
"" | Flat / no image (where allowed) |
Character pack layers — one picture inside an expression — are a different shape: path (not file), plus frames, fps, drive, x / y / w / h, and per-layer modulate / scale / opacity. A layer that uses file is dropped — use path. → Expressions and layers
Where "" is allowed: chrome faces ("" = flat / no image); source ("" = keep empty); char.transition ("" = not specified); an SFX name ("" = silent). It is not a universal value — check the field.
→ Theme and the dialogue box · Choice and input looks
Position on screen
Per-surface. Either absolute x / y, or anchor_h / anchor_v plus offset_x / offset_y. Optional width / height, min/max, padding.
Host — where the surface offers it — differs: dock to the window (screen), beside the dialogue box (panel), or overlay for free choice menus.
→ Places on stage · Gameplay HUD · Sprites and objects
Conditions and “only when”
Split — three unrelated shapes share only the word “condition”:
| Shape | Where | Effect |
|---|---|---|
when | Commands (data / direction) | Skip this command if the expression is falsy |
show_if / disable_if | Screen buttons / choice rules | Hide or disable until the condition is true |
jump_if / [if …] / next_if | Story | Branch on flags |
→ Reacting to flags live · Choices and memory · Expressions
Sticky vs this moment (apply)
Shared.
| Value | Effect |
|---|---|
persistent (usual default) | Stays until reset, override, or new game |
node_local | Reverts after this moment |
Used on panel, labelplate, obj, and similar command families.
→ Sticky state and clear · Reacting to flags live
Live links to flags (bind)
Shared — the shape is the same; the surfaces that offer it differ.
"bind": {
"opacity": { "flag": "lamp_on", "map": { "true": 1, "false": 0.2 } }
}
Surfaces: sprites, objects, characters, backgrounds, panels, and others that list bind keys in their command page.
| Mode | Meaning |
|---|---|
map | Discrete flag value → property |
linear | Numeric range remap |
direct | Pass the flag value through |
→ Reacting to flags live · character look: Expressions and packs
Click, hover, focus (hooks)
Shared vocabulary, per-surface events. The shape is the same; which events exist depends on the surface (screen button vs sprite vs choice item).
"interaction": {
"focusable": true,
"hit_test": "rect",
"hooks": {
"on_click": "screen:pause"
},
"hooks_override": {}
}
| Key | Meaning |
|---|---|
hooks | Event → string verb, command object, or array of those |
hooks_override | Override / clear inherited events (null removes) |
focusable / focus_order | Focus |
hit_test | rect | alpha | polygon |
A menu button carries its action here — interaction.hooks.on_click. Verb inventory: Actions and hooks.
→ Buttons and actions · Sprites and objects
Looks per state (state_visual)
Shared. Per-interaction-state faces: normal, hover, focus, pressed, disabled, optional fallback_order.
Each state may set textures / modulate, source pack compose, shader_params, or a short animation / animations block (not both). shader on a state is clear-only (null to clear) — shader_params is kept when present.
→ Choice and input looks · Buttons and actions
Layering one look on another
Shared.
| Tool | Meaning |
|---|---|
"extends" | Merge keys (panel presets) or layers (character expressions) — different tools |
"style": "name" | Sugar for { "source": "name" } |
"source": "name" | Load themes/<name>.json (+ locale), deep-merge local keys |
path with / | Under the themes tree |
Nested source up to depth 3. Merge: missing = inherit; null = delete; "" = keep empty; present = override.
→ Reusing settings · Choice packs
Effects (shaders)
Per-surface. Accepts a bare string (a stem under shaders/) or an object, and null clears — but which forms and target values each surface allows differs:
| Surface | Accepts | target allowed | Default |
|---|---|---|---|
char | string or object | full | full |
bg / stage | string or object | full | full |
sprite | object only | full | full |
obj | object only | full | full |
panel | object only | bg | full | bg |
| screens / choices | object only | bg | full | bg |
| theme plate (panel face) | string or object | bg | bg |
Only char / bg / stage (and theme plates) take a bare string; the rest need the object.
Object keys:
| Key | Meaning |
|---|---|
name | Stem under shaders/ (required) |
params | Uniforms |
target | bg | full (see table) |
pass | direct | subviewport (default subviewport) |
margin | Number or { left, top, right, bottom } — needs a model background on bg / stage |
panel and screens forbid full + direct.
Where an effect sits: one shader per slot / instance — the whole composited result — never per layer or per part:
- Character: one shader over the whole slot (all layers composited). Not per layer.
- Object: one shader over the whole instance; text parts take no shader.
- Sprite / background: one each.
Full-screen sticky: screen_shader.
→ Shaders
modulate and shader_params
Per-surface. modulate is the most inconsistent shared-looking key:
| Surface | modulate | Type | Scope |
|---|---|---|---|
| character layer | yes | hex string | per layer |
| character slot | yes | color | whole slot |
sprite | yes | color | whole sprite |
bg / stage | yes | hex string | the plate |
obj | yes | hex | whole instance |
panel | no | — | — |
state_visual entry | yes | per state | per state |
shader_params (uniforms) is a sibling of shader on char / bg / stage / obj; sprite and panel have no shader_params — put uniforms in the shader object’s params.