Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Choice packs

A choice pack is a JSON file under themes/ that skins choice buttons or supplies group/item chrome for compose (source). The pack name is the file stem: "style": "choice_button" → themes/choice_button.json.

// themes/choice_button.json — button element pack
{
  "min_width": 220,
  "corner_radius": 0,
  "padding_left": 18,
  "padding_right": 18,
  "padding_top": 4,
  "padding_bottom": 6,
  "normal_texture": "sprites/button-normal.png",
  "hover_texture": "sprites/button-hover.png",
  "pressed_texture": "sprites/button-down.png",
  "focus_texture": "sprites/button-hover.png",
  "texture_9slice": [6, 6, 6, 6],
  "font_color": "#3a2a1a",
  "font_hover_color": "#6b4420",
  "font_pressed_color": "#8a5a28",
  "font_focus_color": "#6b4420"
}

Usually you need

ApproachWhenWhat you put in the file
Button element packStacked text buttonsTextures / flat colours / fonts (table below)
Group compose packFree / sprite / overlay menuscontainer + item (+ optional shuffle / show_numbers) — same shapes as story choices
Name onlyMost stories"style": "choice_plain" in layout.choices or on the node

How style / source resolve: Styling model. Node fields: Choices.

Two pack roles

RoleReferenced byTypical contents
Button elementlayout.choices.style, node choices.style, choice_styleFlat button chrome keys (this page)
Group / composechoices.source, container.source, item.sourcecontainer, item, toggles — story Choices shapes; usually omit items

Nested source is allowed (depth capped). Locale overlays: themes/<name>_<locale>.json.

Button element pack keys

KeyTypeEffect
min_widthnumberMinimum button width
corner_radiusnumberRounded corners on flat faces
border_widthnumberFlat border width
padding_left / padding_right / padding_top / padding_bottomnumberContent margins
normal_texture / hover_texture / pressed_texture / focus_texturetexture spec or ""Nine-slice / image faces; empty string = flat fill
texture_9slice[L, T, R, B]Slice margins for textures
normal_bg / hover_bg / pressed_bg / focus_bgcolor stringFlat fills
normal_border / hover_border / pressed_border / focus_bordercolor stringFlat borders
font_color / font_hover_color / font_pressed_color / font_focus_colorcolor stringCaption colours
states.<state>.paddingsides objectPer-draw-state padding override (pressed, …)
interaction.hooksobjectDefault item hooks merged under items
icon / hover_icon / pressed_icon / focus_iconpath stringOptional glyphs (same as item style)
icon_max_widthnumberIcon width cap
click_sfx / hover_sfxstring or nullPer-channel UI SFX for button (non-sprite) choices. Omit = sounds.button_*; "" / null = silent

Texture specs: string path, or richer texture objects — Texture specs. Empty texture strings keep flat colour chrome (see choice_plain.json).

Same click_sfx / hover_sfx keys are allowed on item style overlays (merged with the pack). If on_hover_enter / on_confirm already includes ui_sfx, that channel’s inherited theme SFX is skipped. Sprite render_mode does not inherit button SFX — add ui_sfx hooks when you want sound.

Does not restyle screen/menu buttons (those use theme root buttons) or the dialogue panel.

Group compose pack example

// themes/choice_yes_no.json — free + sprite + overlay
{
  "show_numbers": false,
  "shuffle": false,
  "container": {
    "layout": {
      "mode": "free",
      "host": "overlay",
      "render_mode": "sprite",
      "anchor_h": "center",
      "anchor_v": "center",
      "width": 750,
      "height": 288
    },
    "style": { "bg_texture": "sprites/choice_bg.png" },
    "transition": { "on_show": "slide_down", "on_hide": "fade", "duration": 0.3 }
  },
  "item": {
    "style": { "text_color": "#00000000" },
    "state_visual": {
      "hover": { "animation": { "property": "position_y", "to": 73, "duration": 0.08 } }
    }
  }
}

Node then: "choices": { "source": "choice_yes_no", "items": [ … ] } with per-item layout.x / y and style.sprite faces. Full key lists: Choices (story node).