Scripting
Ionize edits and runs Luau. The public API surface is documented in the API reference and mapped against sUNC on the compatibility table.
Folders
scripts/. Scripts you open and run from Explorer.autoexec/. Scripts that run automatically on attach.bin/. Supporting files kept next to the workspace.
Portable copies keep those folders next to Ionize.exe. Installed copies use %LOCALAPPDATA%\Ionize.
Run path
- Open or create a
.luatab. - Attach when the status control shows the target is ready.
- Execute from the toolbar.
- Read executor-side results and errors in the console drawer. In-game print stays in the game console.
Sharing state between scripts
The environment returned by getgenv() is shared across every Ionize thread, so it is the simplest place to pass values between scripts.
getgenv().saved = { coins = 100 }
print(getgenv().saved.coins)Reading and writing files
File functions operate inside the workspace folder. Write a file, read it back, and list what is already on disk.
writefile("notes.txt", "hello from Ionize")
print(readfile("notes.txt"))
for _, name in ipairs(listfiles("scripts")) do
print(name)
endHooking functions
hookfunction replaces a function and returns the original, so you can intercept a call, run your own code, then hand control back.
local oldKick = hookfunction(game.Players.LocalPlayer.Kick, function(...)
print("kick intercepted")
return oldKick(...)
end)Listening to events
Connect to Roblox signals directly, or create your own with IonSignal.new.
game.Players.LocalPlayer.CharacterAdded:Connect(function(character)
print("spawned as " .. character.Name)
end)
local channel = IonSignal.new()
channel:Connect(function(value)
print(value)
end)
channel:Fire("ping")Drawing on screen
Build a render object with Drawing.new, then set its properties. It draws above the game viewport.
local box = Drawing.new("Square")
box.Visible = true
box.Position = Vector2.new(200, 200)
box.Size = Vector2.new(120, 80)
box.Color = Color3.fromRGB(25, 93, 204)Console output
Print to the optional console window. Each call creates the window if it does not exist yet.
rconsoleprint("plain text")
rconsolewarn("yellow warning")
rconsoleerror("red error")Game explorer
The explorer panel shows both your local scripts and the live instance tree of the attached game. Refreshing the game tree walks the place and lists every instance, with scripts flagged by class. Folders expand and collapse like a normal explorer.
The scripts only toggle filters the tree down to just Script, LocalScript, and ModuleScript instances. Click a script to decompile it back to source with the built in Luau decompiler. The call yields while a worker thread runs, so the game stays responsive. The button next to it dumps the raw bytecode as hexadecimal text. Either way the result opens as a regular tab you can edit and execute. See Decompiler for options and the pipeline.
Saving a place
The save place button in the explorer writes the whole attached place to the workspace as a .rbxlx file. Every script is queued on the decompiler worker pool; the file is written after those jobs finish. The file lands at Place_<placeId>.rbxlx and the workspace folder opens for you. Scripts can do the same from Luau with the saveinstance global. With no arguments it saves the whole place to.rbxlx. Pass a single instance to save just that instance to .rbxmx.
saveplace()
saveinstance()
saveinstance(game.Workspace)Cleaning obfuscated scripts
When a script you want to read has been obfuscated, run its source through the deobfuscate global. It returns a cleaned version with string decrypting expressions folded into plain literals and machine generated names replaced with readable ones. Your original code is never executed, and anything the cleaner cannot prove safe is left untouched.
local source = decompile(script)
local clean, err, kind = deobfuscate(source)
print(kind, clean or err)Identifying obfuscators
Before cleaning a script, you can ask what protects it. The detectobfuscation global returns the name of the obfuscator a script or bytecode input uses, or "none" when nothing is recognized. It never executes the input.
local kind = detectobfuscation(sourceText)
print(kind)Scheduling work
Run a function on a new thread with task.spawn, or after a delay with task.delay.
task.spawn(function()
print("runs on a new thread")
end)
task.delay(2, function()
print("runs two seconds from now")
end)