Skip to main content

Runtime API

This is the set of global functions and object methods that an exported program uses at runtime. You mostly need it when writing your own Lua on top of a UI Only Export, or when hand‑editing a Full Export's logic/ files.

These functions live in utils/functions.lua; the Screen and component methods live in components/.

Globals

Declared in utils/vars.lua:

GlobalTypeDescription
runningbooleanThe main loop runs while this is true. Set it false to quit.
screenstableEvery Screen object, filled in by screens/*.lua.
monitorstableWrapped monitor peripherals, refreshed by updateMonitors().
workingScreenstableNames of the screens shown on startup.
your variablesanyEach project variable becomes a global here.

Screen functions

Available in Full and UI Only exports (utils/functions.lua).

getScreen(name)

Returns a registered screen. name may be:

  • "terminal" — the working screen currently bound to the computer's terminal;
  • "monitor:<peripheral name>" — the screen on a specific monitor;
  • a screen's own name, e.g. "Screen_1".
local screen = getScreen("terminal")

📝 Note — Logic Only: In a Logic Only Export, getScreen() is a stub that always returns a single shared screen object, regardless of the name.

Switches which screen is active on a display, reassigns monitors, and redraws. This is what the navigate to screen block calls.

navigate(screen.name, "Screen_2")

drawScreens()

Resolves layout and redraws every working screen. UI Only exports call this once at the end of startup.lua; you can call it yourself after changing the UI.

refreshScreen()

Alias for drawScreens().

updateMonitors() / setupMonitorsToScreens(old, new)

Re‑scan attached monitor peripherals and (re)assign screens to compatible displays based on each screen's displayType and monitor size constraints. Called automatically; you rarely invoke these directly.

Screen methods

A Screen is created in each screens/*.lua file. Useful methods:

MethodDescription
screen:getChild(name)Return the child element with that name (or nil).
screen:childSetProp(name, prop, value)Set a child's property and redraw. Uses a set<Prop> method if one exists, else assigns directly.
screen:addChild(element)Register an element on the screen.
screen:addDrawOrder(name)Add a top‑level element to the draw order.
screen:getTopTouchedElement(x, y)The top‑most element at a coordinate (hit‑testing).
screen:draw()Draw the screen and run its onUpdate / onceLoaded.
screen:setBlinking(state, x, y)Toggle the cursor blink (used by inputs).

screen.events

The handlers your block logic attaches to:

FieldShapeFired by
onceLoadedfunction()the first time the screen is drawn
onUpdatefunction()every draw
onKeyPress{ [keyName] = function() }key events
onTimerlist of { func, last, interval }the timer tick
onRedstonefunction()redstone changes
onModemMessage{ ["ch_<n>"] = function(side, ch, reply, msg, dist) }modem messages
local screen = getScreen("Screen_1")

screen.events.onceLoaded = function()
screen:childSetProp("label1", "text", "Ready")
end

table.insert(screen.events.onTimer, { func = function()
-- runs every 2 seconds
end, last = 0, interval = 2 })

Element methods (BaseObject)

Every component inherits these from BaseObject:

MethodDescription
el:setText(text)Set the text and fire its text_changed event.
el:setVisible(visible)Show or hide the element.
el:isVisible()Whether it's currently visible.
el:getScreen()The screen that owns it.
el:getMonitor()The monitor/terminal it draws to.
el:checkTouch(x, y)Whether a coordinate is inside it.

Element events

Each element has an events table. Your “when <element> <event> blocks register functions here, and the main loop calls them:

local btn = screen:getChild("button1")

btn.events["clicked"] = function(x, y) end
btn.events["released"] = function(x, y) end

The events available depend on the element type — for example a Button fires clicked, focused, and released, while a Slider fires value_changed.

Reading & writing properties

Property changes should go through childSetProp so the screen redraws and any setter runs:

-- set (redraws automatically)
screen:childSetProp("progressbar1", "progress", 75)
screen:childSetProp("label1", "text", "Done")
screen:childSetProp("button1", "visible", false)

-- read (direct access is fine)
local current = screen:getChild("slider1").value

childSetProp looks for a method named set<Prop> (e.g. setText, setVisible) and calls it if present; otherwise it assigns the field directly. Either way it redraws.

A minimal hand‑written program

Putting it together — the kind of loop you'd add to a UI Only export to make it interactive:

local screen = getScreen("terminal")

screen:getChild("button1").events["released"] = function()
screen:childSetProp("label1", "text", "Clicked!")
end

while running do
drawScreens()
local event, p1, p2, p3 = os.pullEvent()
if event == "mouse_click" then
local hit = screen:getTopTouchedElement(p2, p3)
if hit and hit.onClickEvent then hit:onClickEvent(p2, p3) end
if hit and hit.onReleaseEvent then hit:onReleaseEvent(p2, p3) end
end
end

See also