Skip to main content

Logic Only Export

Logic Only Export is the opposite of UI Only: it ships your block logic and nothing about the UI. There are no UI component classes and no screen layouts — just your code, the helper functions it needs, and a lightweight loop to drive events. It's built for headless programs: turtle automation, redstone controllers, network/modem nodes, timers, and anything that doesn't draw an interface.

In the export window this is the Code Only option: "Screen Logics with no screens or UI components." ("Code Only" and "Logic Only" refer to the same mode.)

What's different from Full

It drops the components/ and screens/ folders entirely, and utils/functions.lua provides a stub screen instead of the UI runtime. See the Generated File Reference for the shared layout.

Full ExportLogic Only Export
logic/ · utils/vars.lua
components/ · screens/❌ removed
utils/functions.luaUI runtime includedstub screen instead of UI runtime
End of startup.luafull interactive looplightweight logic loop

Because there are no components or screens, utils/functions.lua does not include the UI rendering functions (drawScreens, navigate, …). Instead it provides a small stub so your logic still has a screen object to attach events to:

local mainScreen = {
events = {
onUpdate = function() end,
onceLoaded = nil,
onceLoadedRunned = false,
onKeyPress = {},
onTimer = {},
onRedstone = function() end,
onModemMessage = {}
}
}

function getScreen(name)
return mainScreen -- always returns the single shared stub screen
end

Single shared screen — In Logic Only mode there is no real per‑screen UI, so every logic file shares this one mainScreen stub. getScreen("anything") always returns the same object. Your event handlers, timers, and onceLoaded code all run against it.

What "Logic Only" means at runtime

startup.lua ends with a trimmed event loop that only handles the non‑UI events — the load hook, timers, key presses, redstone, and modem messages:

local mainTimerId = os.startTimer(0.05)

while running do
local screen = getScreen()
if (not screen.events.onceLoadedRunned and screen.events.onceLoaded) then
screen.events.onceLoadedRunned = true
screen.events.onceLoaded()
end

local event, p1, p2, p3, p4, p5 = os.pullEvent()

if event == "close" then running = false; return end

if event == "timer" and p1 == mainTimerId then
-- run any "Every N seconds" timers …
mainTimerId = os.startTimer(0.05)
elseif event == "redstone" then
screen.events.onRedstone()
elseif event == "modem_message" then
screen.events.onModemMessage["ch_" .. p1](p2, p3, p4, p5)
elseif event == "key" and p1 then
-- run any "when key is pressed" handlers …
end
end

There is no drawing and no mouse/touch handling — those only exist when UI is exported.

Which blocks make sense here

Logic Only is ideal for blocks that don't depend on the canvas:

  • Events: when this screen loads, Every N seconds, when key is pressed, when redstone input changes, when modem receives message, when any event occurs.
  • CC: Tweaked APIs: Turtle, Redstone, Rednet, Modem, Peripheral, Files, HTTP, System/OS, Disk, and the mod plugins (Create, Mekanism, Advanced Peripherals).

Blocks that get/set UI element properties or navigate between screens have no effect here, since there is no UI to act on.

logic/Screen_1.lua — a redstone + timer example
local screen = getScreen("Screen_1")

screen.events.onceLoaded = function()
redstone.setOutput("top", false)
end

table.insert(screen.events.onTimer, { func = function()
redstone.setOutput("top", not redstone.getOutput("top")) -- blink every second
end, last = 0, interval = 1 })

Running it

  1. Export with Code Only.
  2. Place the folder in a computer's (or turtle's) directory.
  3. Run startup.lua. The program runs your logic loop with no interface.

See also