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

Free choices

Most menus are a stack of buttons. Free choices place options at absolute positions — hotspots on the stage, sprite faces, inspect scenes. Same story choices object; different container.layout.

Most stories

  • Keep script > lines for ordinary menus (stack).
  • For clickable art: write the choice as JSON in story.json with "mode": "free", item x / y, often "render_mode": "sprite".
  • Do not combine shuffle or stack gap with free.

Where this lives

IdeaPath
Group modechoices.container.layout.mode: "stack" | "free"
Hostpanel (dialogue slot) or overlay (full screen)
FacesItem / pack style.sprite + state_visual
Defaultsgame.json → layout.choices
"choices": {
  "show_numbers": false,
  "container": {
    "layout": { "mode": "free", "host": "overlay", "render_mode": "sprite" }
  },
  "items": [
    { "text": "Door", "target": "enter", "layout": { "x": 420, "y": 280 } },
    { "text": "Leave", "target": "NEXT", "layout": { "x": 900, "y": 600 } }
  ]
}

Worked pack: examples/example-05-ui-and-polish/themes/choice_yes_no.json.

Same items, same mode: free and render_mode: sprite. The only difference is host: overlay leaves them floating at their absolute x / y, while panel puts them inside the dialogue plate, which grows to fit.

Stack vs free

stackfree
PlacementVertical listAbsolute x / y
gap / shuffleOKForbidden
Typical lookTheme buttonsSprites + state_visual

Hover / pressed looks: Shared shapes → state_visual. Full keys: Choices (story). Ordinary menus: Choices and memory · Choice and input looks.