Everything the in-game Script tab exposes. Hand this whole page to an AI to have it write scripts for you.
+=, continue, and string interpolation with backticks `{x}`. No goto.print(...) output and any error appear in the Script tab's log panel.string, table, math, os (time/clock/date only, no os.execute/files), coroutine, bit32, utf8, buffer, vector, debug, and the base functions (pairs, ipairs, pcall, tonumber, type, …). There is no io, filesystem, or networking.
Addresses are plain numbers. A double exactly represents any 64-bit user-mode address.
| Function | Returns | Notes |
|---|---|---|
readfloat(addr) | number / nil | 32-bit float; nil if unreadable |
writefloat(addr, value) | boolean | success flag |
readint(addr) | number / nil | signed 32-bit int |
writeint(addr, value) | boolean | 32-bit int |
readptr(addr) | number / nil | 64-bit pointer value, for walking pointer chains |
writeptr(addr, value) | boolean | 64-bit |
moduleaddr([name]) | number | base address of a module. No arg = Vortex.exe base; e.g. moduleaddr("kernel32.dll") |
print(...) | none | writes to the Script tab log |
Resolve [[base+o1]+o2]+…:
local addr = moduleaddr() + 0x1234000 -- static base
addr = readptr(addr) + 0x10 -- follow one hop
addr = readptr(addr) + 0x8 -- another hop
print(readfloat(addr))
These flip the same toggles as the overlay's Player tab. For any boolean argument, omit it to toggle.
| Function | Behavior |
|---|---|
fly(on?) | Fly. Space = up, Ctrl = down, WASD walks. Requires a Y axis saved in the Coordinates tab. |
noclip(on?) | Auto-noclip (phase through a wall you push into). Requires X, Y, Z saved. |
infjump(on?) | Infinite jump. Every Space tap gains height. Requires Y saved. |
speed(mult) | speed(2.5) = 2.5×. speed(true) enables at the current rate. speed(), speed(false), speed(0) disable. Works standalone, no axes needed. |
teleport(i) | Built-in spot, 1-based: 1=Backrooms End, 2=Banlands Roof, 3=Obby End. Requires X/Y/Z saved. |
teleport(x, y, z) | Teleport to arbitrary coordinates. Requires X/Y/Z saved. |
speed() is the exception and works alone.
gui(title?) creates a retained window (drawn every frame, even with the Tuff menu closed) and returns a handle. Every widget/layout method returns the handle, so calls chain. Callbacks run on the render thread when the widget is used, so keep them light.
local w = gui("Title") -- title optional (defaults to "Script")
| Method | Callback | Notes |
|---|---|---|
w:button(label, fn?) | fn() | fires on click |
w:toggle(label, initial?, fn?) | fn(state) | checkbox; state is a boolean. initial (bool) optional |
w:slider(label, lo, hi, init?, fn?) | fn(value) | number; init optional, defaults to lo |
w:input(label, initial?, fn?) | fn(text) | text box; fires on Enter. 255-char max |
w:combo(label, items, fn?) | fn(index, text) | items = array table of strings; index is 1-based |
w:color(label, r?, g?, b?, fn?) | fn(r, g, b) | RGB each 0..1; default white |
w:label(text) | none | static text |
| Method | Notes |
|---|---|
w:setpos(x, y) | position the window (applied once; user can drag afterward) |
w:setsize(w, h) | size the window (applied once) |
cleargui() | remove all script windows and release their callbacks |
A callback may itself call cleargui() then gui(...) to swap menus. This is supported and safe mid-frame.
gui("X") makes a second "X" window, so call cleargui() first when rebuilding.gui error: …; they don't crash the game.getpos() from Lua. To read player position, know the addresses (via the Coordinates tab or a pointer chain) and use readfloat.cleargui()
local w = gui("Cheats")
w:setpos(60, 60):setsize(260, 0)
w:toggle("Fly", function(on) fly(on) end)
w:toggle("Noclip", function(on) noclip(on) end)
w:toggle("Infinite Jump", function(on) infjump(on) end)
w:slider("Speed", 0.5, 5.0, 1.0, function(v) speed(v) end)
w:combo("Teleport", {"Backrooms End", "Banlands Roof", "Obby End"},
function(i, name) teleport(i); print("TP:", name) end)
w:button("Speed off", function() speed(false) end)
local base = moduleaddr() + 0x01A2B000 -- example static offset
local hp = readptr(base) + 0x40 -- follow one pointer, +0x40
local w = gui("HP")
w:label(`current: {readfloat(hp)}`)
w:button("Set HP = 100", function() writefloat(hp, 100) end)
w:input("Set HP to…", function(txt)
local n = tonumber(txt)
if n then writefloat(hp, n) end
end)
local pageA
local function pageB()
cleargui()
local b = gui("Page B")
b:label("You are on B")
b:button("← Back", pageA)
end
function pageA()
cleargui()
local a = gui("Page A")
a:label("You are on A")
a:button("Next →", pageB)
end
pageA()
Questions about a script? Ask in the Discord.