Declaring settings
The manifest’s settings array becomes a real page in the settings rail —
rendered, stored, and live-applied exactly like a builtin’s:
"settings": [
{ "key": "zone", "label": "Time zone", "kind": "text", "default": "Asia/Tokyo" },
{ "key": "h24", "label": "24-hour", "kind": "toggle", "default": true },
{ "key": "work", "label": "Work minutes", "kind": "slider",
"min": 15, "max": 90, "default": 25 },
{ "key": "unit", "label": "Unit", "kind": "choice",
"options": ["celsius", "fahrenheit"], "default": "celsius" }
]
| Kind | Extra fields | Lua receives |
|---|---|---|
toggle | boolean | |
slider | min max step (default 0.01) | number |
choice | options | the chosen option string |
text | string | |
status | read-only display line (your logic sets it) | |
button | no value — pressing it fires on_command |
inline_with_previous: true joins a setting onto the previous setting’s
row — compound rows like a text field with its choice chips sharing one
bar.
Live-apply
function M.on_configure(host, s)
zone, h24 = s.zone or zone, s.h24
host.push_data("worldclock", payload())
end
on_configure fires with the full current settings table — at startup
(before or right after on_start) and on every change. There is no save
button and no restart anywhere in Perch; treat every change as immediate.
Storage
A mod-scoped key-value store — declare the storage scope:
perch.storage.set("history", { 3, 4, 4, 6, 9 }) -- any JSON-shaped value
local hist = perch.storage.get("history") -- nil if absent
- Persisted across restarts, private to your mod, capped at 64 KB total. A write that would exceed the cap is discarded — keep it for state, not data hoards.
- Values round-trip as JSON: tables, strings, numbers, booleans. No functions, no userdata.
What goes where
| Data | Home |
|---|---|
| user preferences | settings (visible, user-owned) |
| accumulated state — histories, last-seen, counters | perch.storage |
| live values for the view | push_data payloads — never persisted |
| anything secret | nowhere — mods have no secret store by design |