Config forms

The pre-run form a script declares: number, text, checkbox, select, color, brush and palette fields.

A script can declare a small form that's shown before it runs. What the user fills in arrives as the app.config table, keyed by each field's id. Fields are plain data — a script never describes UI — and the editor renders and validates them. Colors, brushes and palettes are how a script asks for something from the user's own stuff: the engine never reads their libraries, so a script gets exactly what they pick.

  • number — A number input. In Lua: number. Options: default (The starting value.); min (The smallest allowed value.); max (The largest allowed value.); optional (Allow it to be left empty.); randomMin / randomMax (The range Randomize picks from, inside min..max (default min..max; without both bounds Randomize leaves it alone). Whole numbers when the bounds and default are.); randomize (false keeps the value when the user randomizes the form.).
  • text — A line of text. In Lua: string. Options: default (The starting text.); optional (Allow it to be left empty.).
  • checkbox — An on/off switch. In Lua: boolean. Options: default (Whether it starts checked.); randomize (false keeps the value when the user randomizes the form.).
  • select — A choice from a fixed list. In Lua: string (the chosen option's value). Options: options (The choices, each { value, label }.); default (The value selected at the start.); randomize (false keeps the choice when the user randomizes the form.).
  • color — A color, picked with the editor's color picker — with the sprite's palette and the recent colors one click away. Give each role its own field (leaf light, leaf dark, bark…) and the user chooses them all. In Lua: string, "#rrggbb" (or "#rrggbbaa" with alpha) — accepted directly wherever a color goes. Options: default (The starting color, "#rrggbb" or "#rrggbbaa" (black if omitted).); randomize (true lets Randomize pick a color too (it keeps the alpha). Off by default: most scripts' colors are tuned.).
  • brush — One of the user's saved brushes, chosen from their brush library. In Lua: table { name, width, height, mask } — pass it to app.defineBrush; absent when optional and left empty. Options: optional (Allow it to be left empty (then app.config.<id> is nil).).
  • palette — One of the user's saved palettes, chosen from their palette library. In Lua: list of "#rrggbb" (or "#rrggbbaa") strings — pass it to app.setPalette, or pick from it with color math; absent when optional and left empty. Options: optional (Allow it to be left empty (then app.config.<id> is nil).).

Example form (JSON) and the script that uses it:

{
  "fields": [
    {
      "id": "leafLight",
      "type": "color",
      "label": "Leaf (light)",
      "default": "#6cc24a"
    },
    {
      "id": "leafMid",
      "type": "color",
      "label": "Leaf (mid)",
      "default": "#3a8f4a"
    },
    {
      "id": "leafDark",
      "type": "color",
      "label": "Leaf (dark)",
      "default": "#23603a"
    },
    {
      "id": "barkLight",
      "type": "color",
      "label": "Bark (light)",
      "default": "#8a5a35"
    },
    {
      "id": "barkDark",
      "type": "color",
      "label": "Bark (dark)",
      "default": "#5a3a22"
    },
    {
      "id": "stamp",
      "type": "brush",
      "label": "Leaf brush",
      "optional": true
    }
  ]
}
local layer, frame = app.getActiveLayerId(), app.getActiveFrameId()
local c = app.config

-- trunk: two bark colors the user chose
app.drawRectangle(layer, frame, 14, 20, 17, 31, { color = c.barkDark, fill = "filled" })
app.drawRectangle(layer, frame, 14, 20, 15, 31, { color = c.barkLight, fill = "filled" })

-- canopy: three leaf colors, with the user's own brush if they picked one
if c.stamp then app.defineBrush("leaf", c.stamp) end
for i, color in ipairs({ c.leafDark, c.leafMid, c.leafLight }) do
  app.drawStroke(layer, frame, { { 8, 18 - i * 4 }, { 24, 18 - i * 4 } },
    { color = color, brush = c.stamp and "leaf" or nil, brushSize = 4 })
end

Branching

Any field can carry a when — { "<earlier field id>": [values] } — and then shows only while each named select holds one of those option values (or checkbox is true/false) and is itself shown. Conditions only look back at earlier selects and checkboxes, so they chain to any depth: switch the root and its whole branch hides. A hidden field is left out of app.config, so the script falls back to its own default — read every field as optional.

{
  "fields": [
    {
      "id": "kind",
      "type": "select",
      "label": "Kind",
      "options": [
        {
          "value": "broadleaf",
          "label": "Broadleaf"
        },
        {
          "value": "conifer",
          "label": "Conifer"
        }
      ],
      "default": "broadleaf"
    },
    {
      "id": "crown",
      "type": "select",
      "label": "Crown",
      "options": [
        {
          "value": "round",
          "label": "Round"
        },
        {
          "value": "weeping",
          "label": "Weeping"
        }
      ],
      "when": {
        "kind": [
          "broadleaf"
        ]
      }
    },
    {
      "id": "droop",
      "type": "number",
      "label": "Droop",
      "min": 0,
      "max": 100,
      "randomMin": 20,
      "randomMax": 80,
      "when": {
        "crown": [
          "weeping"
        ]
      }
    },
    {
      "id": "tiers",
      "type": "number",
      "label": "Tiers",
      "min": 2,
      "max": 12,
      "when": {
        "kind": [
          "conifer"
        ]
      }
    },
    {
      "id": "newLayer",
      "type": "checkbox",
      "label": "Draw on a new layer",
      "randomize": false
    }
  ]
}

Randomize

Every form gets a Randomize button. It rolls each number within randomMin..randomMax (default min..max; a number without both bounds is kept), picks any select option and flips checkboxes; colors only roll with randomize: true, and text, brushes and palettes are never touched. Set randomMin/randomMax to the range that still looks good, and randomize: false on settings that aren't about the art (new layer, respect selection...).

As Markdown: config-forms.md.