Luau Scripting
Setonix Luau plugins now get a high-level Setonix runtime object that wraps the low-level bridge. The goal is to move everyday scripting away from raw JSON-shaped events and toward wrapped players, tables, cells, commands, and generic utility helpers.
The raw bridge is published as SetonixRaw and is also available through Setonix.raw when you need direct access, but the old standalone State, Events, and Server globals are no longer part of the public scripting surface.
Quick Start
Section titled “Quick Start”local deck = Setonix.cells.get(0, 0)local stack = Setonix.cells.get(0, 1)
Setonix.events.on("player_join", function(event) event.player:sendMessage("Welcome to " .. Setonix.namespace()) event:setToolbar({ editable = false, actions = { Setonix.server.toolbarAction("blackjack_hit", "Hit"), Setonix.server.toolbarAction("blackjack_stand", "Stand"), }, })end)
Setonix.commands.register("stand", function(event) event:reply("Standing with current hand.") event:cancel()end)
Setonix.events.action("blackjack_hit", function(event) deck:moveTopTo(stack, 1)end)API Shape
Section titled “API Shape”You can use either the flat helpers or the namespaced variants:
Setonix.on(...)orSetonix.events.on(...)Setonix.command(...)orSetonix.commands.register(...)Setonix.player(id)orSetonix.players.get(id)Setonix.players()orSetonix.players.all()Setonix.currentTable()orSetonix.tables.current()Setonix.getTable(name)orSetonix.tables.get(name)Setonix.cell(...)orSetonix.cells.get(...)Setonix.process(...)orSetonix.requests.*(...)Setonix.send(...)orSetonix.server.*(...)
The top-level helpers are convenient for short scripts. The namespaced entry points are better once a script grows beyond a few callbacks.
Events
Section titled “Events”Register listeners
Section titled “Register listeners”Setonix.events.on("message", function(event) Setonix.log("chat from " .. tostring(event.source) .. ": " .. event.message)end)
Setonix.events.action("blackjack_stand", function(event) if event:isFrom(event.player) then event:reply("You pressed stand.") endend)Supported aliases include:
player_join,player_joined,user_join,user_joinedmessage,chattoolbar_action,actionobjects_moved,objects_spawned,objects_removedcell_hide_changed,cell_hidden- many direct snake_case aliases for client, hybrid, and server event names from the Setonix event model
Event wrapper
Section titled “Event wrapper”Every high-level event includes:
event.raw: the original raw event tableevent.details: the low-level event details userdataevent.player: wrapped player when availableevent.cell,event.from,event.to: wrapped cells when present on the raw eventevent.tableRef: wrapped table for table-bound eventsevent.action: convenience alias foractionIdevent.cancelled: read/write cancellation state
Methods:
event:cancel()event:isCancelled()event:schedule(playableEvent, target)event:reply(message, author)event:broadcast(message, author)event:setToolbar(toolbar)event:getPlayer()event:getCell()event:isFrom(playerOrId)event:table()
Commands
Section titled “Commands”Setonix.command(name, handler) and Setonix.commands.register(name, handler) create simple chat commands for both !name and /name by default.
Setonix.commands.register("deal", function(event) event:reply("Dealing a card...") event:cancel()end)Inside the handler:
event.commandcontains the matched command nameevent.argumentscontains whitespace-split arguments
Players
Section titled “Players”local player = Setonix.players.get(7)
if player:isOnline() then player:sendMessage("Your turn")endPlayer fields and methods:
player.idplayer:sendMessage(message, author)player:setToolbar(toolbar)player:isOnline()player:equals(playerOrId)
Tables And Cells
Section titled “Tables And Cells”Tables and cells are live views into the current state. They read from the underlying world state whenever queried.
local tableRef = Setonix.tables.current()local discard = tableRef:cell(4, 0)
if discard:hasObjects() then discard:clear()end
tableRef:spawnObject({ x = 0, y = 0 }, Setonix.namespace() .. ":cards", { variation = "heart-ace", hidden = true,})Table methods:
tableRef.nametableRef:raw()tableRef:cell(positionOrX, y)tableRef:getCell(positionOrX, y)tableRef:cells()tableRef:position(x, y)tableRef:spawn(positionOrX, y, objects, target)tableRef:spawnObject(positionOrX, y, asset, options, target)
State helpers:
Setonix.state.raw()Setonix.state.tableName()Setonix.state.tables()Setonix.state.info()Setonix.state.players()Setonix.state.teamMembers()Setonix.state.currentTable()
Cell methods:
cell.table,cell.x,cell.ycell:key()cell:toGlobal()cell:copy()cell:withTable(name)cell:equals(positionOrCell)cell:raw()cell:objects()cell:tiles()cell:isEmpty()cell:topObject()cell:object(index)cell:topObjects(count)cell:countObjects()cell:hasObjects()cell:spawn(objects, target)cell:spawnObject(asset, options, target)cell:remove(objects, target)cell:clear(target)cell:show(object, target)cell:hide(object, target)cell:moveTo(targetCell, objects, target)cell:moveTopTo(targetCell, count, target)cell:shuffle(force)cell:roll(object, force)
Collections And Scoring
Section titled “Collections And Scoring”The Setonix.collections and Setonix.scoring namespaces are intentionally generic so game-mode scripts can build their own domain logic without the API assuming a particular pack structure.
local order = Setonix.collections.shuffle({ "a", "b", "c" })local total = Setonix.scoring.bestTotal(items, function(item) return item.valuesend, 21)Available helpers:
Setonix.collections.copy(values)Setonix.collections.shuffle(values)Setonix.scoring.bestTotal(items, resolverOrMap, maxScore)
Server Helpers
Section titled “Server Helpers”The server namespace collects common outbound actions:
Setonix.server.broadcast("Round started")
Setonix.server.setToolbar({ editable = false, actions = { Setonix.server.toolbarAction("draw", "Draw"), },}, event.source)Available helpers:
Setonix.server.send(event, target)Setonix.server.process(event, force)Setonix.server.message(message, target, author)Setonix.server.broadcast(message, author)Setonix.server.setToolbar(toolbar, target)Setonix.server.toolbarAction(id, label, enabled)Setonix.server.events.*builders for hybrid and server events such asobjectsMoved,objectsRemoved,cellHideChanged,message,toolbarUpdated,dialogsClosed, and more
The flat aliases Setonix.send, Setonix.process, Setonix.message, Setonix.broadcast, Setonix.setToolbar, and Setonix.toolbarAction remain available too.
Requests
Section titled “Requests”Client-style requests now have a high-level namespace too, so scripts no longer need to build request tables by hand.
Examples:
Setonix.requests.teamJoin(team, force)Setonix.requests.teamLeave(team, force)Setonix.requests.cellRoll(cell, object, force)Setonix.requests.shuffleCell(cell, force)Setonix.requests.packsChange(packs, force)Setonix.requests.boardsSpawn(tableName, assets, force)Setonix.requests.boardRemove(cell, index, force)Setonix.requests.boardMove(tableName, fromCell, toCell, index, force)Setonix.requests.dialogClose(id, value, force)Setonix.requests.images(ids, force)Setonix.requests.modeChange(location, force)Setonix.requests.modePlain(force)Setonix.requests.authenticate(signature, publicKey, force)Setonix.requests.toolbarAction(actionId, force)
Object Helpers
Section titled “Object Helpers”local hiddenAce = Setonix.object(Setonix.namespace() .. ":cards", { variation = "spade-ace", hidden = true,})Use Setonix.object(asset, options) to create spawnable object payloads without manually building raw tables.
Raw Escape Hatch
Section titled “Raw Escape Hatch”The low-level bridge is still available when needed:
SetonixRaw.Server:Send({ type = "MessageSent", user = 0, message = "raw access still works",}, nil)Raw access points:
SetonixRaw.EventsSetonixRaw.StateSetonixRaw.ServerSetonixRaw.eventsSetonixRaw.stateSetonixRaw.serverSetonix.raw.EventsSetonix.raw.StateSetonix.raw.ServerSetonix.raw.eventsSetonix.raw.stateSetonix.raw.server