Cheat sheet
Everything on one scannable page. Full spec: show.json format · tutorial: first show.
Show files are JSONC (comments allowed). Vars are bare (heat); devices use @ (@strip).
Top-level sections
Section titled “Top-level sections”schemaVersion (=1, required) · name · board · devices · vars · palette · defs · lists · inputs · scripts · states (required) · rules
There are no scenes/sequences/effects sections — everything is a script.
Scripts (flow control)
Section titled “Scripts (flow control)”A script is one recursive container: { loop, speed, children }. There is no container mode — each child declares its own flow (default serial):
child flow |
gates next sibling | awaited by parent | use for |
|---|---|---|---|
serial (default) |
yes | yes | a step in a script |
parallel |
no | yes | a join / a looping look |
detached |
no | no | fire-and-forget |
loop: true — repeat forever; loop: <N> — repeat N times. Looping children are auto-detached. speed — number/expr or { chase, rate }.
Launch from states: start/run = begin (background vs awaited-via-.done), stop = end.
Devices — @id
Section titled “Devices — @id”| field | units / values | notes |
|---|---|---|
kind |
ledstrip | digital | pwm | screen |
omit for a segment |
count |
integer ≥ 1 | channels / pixels (default 1) |
pin |
GPIO number | validated against board; omit for a screen |
order |
e.g. GRB, RGBW |
LED color order |
brightness |
0..255 | LED master (default 120) |
width + height |
pixels | screen framebuffer size (0 = backend default) |
segmentOf + start + count |
parent id, index, length | names a slice of a strip |
Inputs → events
Section titled “Inputs → events”type is digital (default) or analog. The state machine decides tap-vs-hold, not the input.
type |
events emitted |
|---|---|
digital |
id.pressed · id.released · id.tapped (short) · id.held (long) |
analog |
id.high · id.low |
Tap-to-toggle: two states both handling id.tapped. Hold-to-run: id.pressed start, id.released stop.
Fields: label, color, pin (omit = virtual), activeLow (bool), pull (up/down), holdMs (tap/held split, default 400), min/max (analog raw range → 0..1), high/low (analog 0..1 thresholds). An input’s live level is readable as a var under its id.
Don’t name an input after an event suffix (pressed/tapped/…) — use a distinct name.
Effect verbs
Section titled “Effect verbs”| verb | value | params |
|---|---|---|
bar |
@device |
color, sec |
comet |
@device |
color, lapSec, tail |
spark |
@device |
color, sec |
chase |
@device |
color, off, sec |
blink |
@device |
color, off, sec, duty |
pattern |
@device |
color (per-pixel expression, 1-D) |
play |
file.wav |
volume, as |
Screen verbs (target a @screen device)
Section titled “Screen verbs (target a @screen device)”| verb | value | params |
|---|---|---|
paint |
@screen |
color (per-pixel expr; reads x,y,w,h,nx,ny) |
fill |
@screen |
color |
rect |
@screen |
color, x, y, w, h, outline |
circle |
@screen |
color, x, y, r, outline |
line |
@screen |
color, x0, y0, x1, y1 |
pixel |
@screen |
color, x, y |
polygon |
@screen |
color, points ([[x,y],…]), outline |
text |
@screen |
value (static string), color, x, y, size, font |
number |
@screen |
value (var/expr), color, x, y, size, digits, font |
image |
@screen |
file (.bmp/.rgb565), x, y |
Modifiers on any child/step: loop (bool/int), speed, intensity, for, every, after, while (or a modifiers object).
Actions (enter / exit · script children · handler do)
Section titled “Actions (enter / exit · script children · handler do)”| action | form |
|---|---|
| start script | { "start": "script" } |
| stop script | { "stop": "script" } |
| run script | { "run": "script" } |
| set var | { "set": "var", "to": <n/expr> } |
| set device | { "set": "@dev", "color": "#.." } or { "set": "@dev", "on": true } |
| ramp var | { "ramp": "var", "to": <n>, "rate": <n> } |
| fade script/var | { "fade": "script", "to": <n>, "rate": <n> } |
| play sound | { "play": "file.wav", "volume": <n> } |
| wait | { "wait": <sec> } |
| emit event | { "emit": "event" } |
Transition = to on a handler (not an action).
States
Section titled “States”"states": { "initial": "Off", "Off": { "enter": [...], "exit": [...], "on": { "power.tapped": "On" }, // string handler = pure transition "after": { "sec": 10, "to": "X" } }, // fire once, N sec after entry "On": { "on": { "fire.pressed": { "do": [...], "to": "Firing", "when": "heat<1" } } }}Handler: string → transition · object → { do, to, when }. A button is enabled only when the current state handles one of its events.
sec, lapSec, wait, after.sec, for, every, after → seconds. rate → units per second. duty, intensity, volume, analog high/low → 0..1. speed → multiplier. brightness → 0..255. color → #RRGGBB or a color expression.
Expressions (any color/number, as a quoted string)
Section titled “Expressions (any color/number, as a quoted string)”Operators: + - * / % · == != < > <= >= · && || ! · a ? b : c
Names: bare var (heat), input value, @effect.prop. Hex 0x... Constants: true false pi.
abs floor ceil round sqrt sin cos tan sign pow mod fracmin max clamp lerp step smoothstep if map random pickrgb(r,g,b) 0..255 → colorhsv(h,s,v) 0..1 → color (h wraps)mix(a,b,t) blend two colors (use mix, not lerp, for colors)map(x,inLo,inHi,outLo,outHi) lerp(a,b,t)Built-in variables
Section titled “Built-in variables”| name | where | value |
|---|---|---|
time |
everywhere | seconds since start |
pi |
everywhere | 3.14159… |
i, count |
pattern (1-D) |
pixel index, pixel total |
x y w h nx ny |
paint (2-D) |
pixel coords, canvas size, normalized 0..1 |
<input> |
everywhere | an input’s live level (0/1 digital, 0..1 analog) |
References
Section titled “References”@device · bare var · script/state by name · input.event · script.done · as (names a play/effect instance) · @effect.prop (in expressions).