# API di scripting Lua di pxstud.io — Moduli di configurazione

> Parte del riferimento di scripting Lua di pxstud.io, la cui panoramica (https://pxstud.io/it/docs/scripting.md) ne spiega le convenzioni. I gruppi di opzioni e i tipi a cui rimanda sono in https://pxstud.io/it/docs/scripting/option-groups.md e https://pxstud.io/it/docs/scripting/types.md. Tutto in un unico file (in inglese): https://pxstud.io/llms-full.txt. L'indice dell'intero sito (in inglese): https://pxstud.io/llms.txt.

## Moduli di configurazione
Uno script può dichiarare un piccolo modulo che viene mostrato prima della sua esecuzione. Ciò che l'utente compila arriva come tabella app.config, indicizzata per l'id di ciascun campo. I campi sono semplici dati (uno script non descrive mai l'interfaccia) e l'editor li mostra e li convalida. Colori, pennelli e palette sono il modo in cui uno script chiede qualcosa dalle cose dell'utente: il motore non legge mai le sue librerie, quindi lo script riceve esattamente ciò che l'utente sceglie.

- `number` — Un campo numerico. In Lua: number. Opzioni: `default` (Il valore iniziale.); `min` (Il valore minimo consentito.); `max` (Il valore massimo consentito.); `optional` (Consente di lasciarlo vuoto.); `randomMin / randomMax` (L'intervallo da cui pesca Casuale, dentro min..max (predefinito min..max; senza entrambi i limiti Casuale lo lascia stare). Numeri interi quando lo sono i limiti e il valore predefinito.); `randomize` (false mantiene il valore quando l'utente rende casuale il modulo.).
- `text` — Una riga di testo. In Lua: string. Opzioni: `default` (Il testo iniziale.); `optional` (Consente di lasciarlo vuoto.).
- `checkbox` — Un interruttore acceso/spento. In Lua: boolean. Opzioni: `default` (Se parte selezionato.); `randomize` (false mantiene il valore quando l'utente rende casuale il modulo.).
- `select` — Una scelta da un elenco fisso. In Lua: string (il valore dell'opzione scelta). Opzioni: `options` (Le scelte, ciascuna { value, label }.); `default` (Il valore selezionato all'inizio.); `randomize` (false mantiene la scelta quando l'utente rende casuale il modulo.).
- `color` — Un colore, scelto con il selettore colori dell'editor, con la palette dello sprite e i colori recenti a portata di clic. Dai a ogni ruolo il suo campo (foglia chiara, foglia scura, corteccia...) e l'utente li sceglie tutti. In Lua: string, "#rrggbb" (o "#rrggbbaa" con alfa), accettata direttamente ovunque serva un colore. Opzioni: `default` (Il colore iniziale, "#rrggbb" o "#rrggbbaa" (nero se omesso).); `randomize` (true permette a Casuale di scegliere anche un colore (mantiene l'alfa). Disattivato di default: i colori della maggior parte degli script sono calibrati.).
- `brush` — Uno dei pennelli salvati dell'utente, scelto dalla sua libreria di pennelli. In Lua: table { name, width, height, mask }: passala ad app.defineBrush; assente se opzionale e lasciata vuota. Opzioni: `optional` (Consente di lasciarlo vuoto (allora app.config.<id> è nil).).
- `palette` — Una delle palette salvate dell'utente, scelta dalla sua libreria di palette. In Lua: lista di stringhe "#rrggbb" (o "#rrggbbaa"): passala ad app.setPalette, oppure scegli al suo interno con la matematica dei colori; assente se opzionale e lasciata vuota. Opzioni: `optional` (Consente di lasciarla vuota (allora app.config.<id> è nil).).

Modulo di esempio (JSON) e lo script che lo usa:

```json
{
  "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
    }
  ]
}
```

```lua
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
```

### Ramificazione
Qualsiasi campo può avere un when — { "<earlier field id>": [values] } — e allora viene mostrato solo finché ogni select indicato ha uno di quei valori di opzione (o ogni checkbox è true/false) ed è a sua volta mostrato. Le condizioni guardano solo select e checkbox precedenti, quindi si concatenano a qualsiasi profondità: cambia la radice e tutto il suo ramo si nasconde. Un campo nascosto non compare in app.config, quindi lo script ripiega sul proprio valore predefinito: leggi ogni campo come opzionale.

```json
{
  "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
    }
  ]
}
```

### Casuale
Ogni modulo ha un pulsante Casuale. Estrae ogni numero entro randomMin..randomMax (predefinito min..max; un numero senza entrambi i limiti resta com'è), sceglie un'opzione qualsiasi dei select e inverte i checkbox; i colori vengono estratti solo con randomize: true, mentre testo, pennelli e palette non vengono mai toccati. Imposta randomMin/randomMax sull'intervallo che continua a funzionare bene e randomize: false sulle impostazioni che non riguardano l'arte (nuovo livello, rispetta selezione...).
