Clockworks Viewer — Lua Scripting

Clockworks runs user-authored Lua 5.4 scripts to react to playback and send control data to other systems (OSC, Art-Net, MIDI). There are two kinds of scripts — cue scripts and the global script — plus a shared extensions file.

Cue scripts vs. the global script

Cue script Global script
Attached to A single cue (per track) The whole project (one, app-wide)
Runs when That cue fires during playback Continuously — you define event handlers it calls
Shape A plain script body; the whole thing runs top-to-bottom on each fire A set of named functions (onMeta, onBeat, …); Clockworks calls the ones you define
Edited via Cue list → edit-script (pencil) on a cue Navbar → Global Script
Stored in The project's scripts sheet, keyed by cue id Same sheet, under a reserved id

Both kinds share one Lua environment — the same global namespace, the same exposed functions, and the same user extensions. A value set as a global in one is visible to the other.

Cue script

The entire body executes each time the cue fires. Example:

-- Fires every time this cue is triggered
sendOSCDest("10.0.0.5", 9000, "/scene/go", 3)
sendMidiNote(1, 60, 127)

Global script

You define handler functions; Clockworks invokes whichever ones exist and silently ignores the rest (an unimplemented handler is never an error). If you don't need a handler, don't define it.

function onMeta(deck, title, artist, album)
    sendOSCDest("127.0.0.1", 9600, "/nowplaying", title, artist)
end

function onDeckSelected(deck)
    -- deck == 0 means "no deck selected"
    sendMidiCC(1, 20, deck)
end

Global handler reference

Handler Signature Called when
onMeta onMeta(deck, title, artist, album) Track metadata changes on a deck
onBeat onBeat(deck, beat, bpm) Beat/tempo update for a deck
onLive onLive(live) Live state toggles on/off
onDeckSelected onDeckSelected(deck) The active deck changes

Argument types:

Exposed functions