World Executor · Roblox VM

Debug

Runtime introspection of Luau functions: read and write constants, upvalues, protos, and stack entries; query debug metadata.

Overview

Luau functions carry more than their code: constants they reference, upvalues they close over, and nested prototypes for the functions defined inside them. This library reads all three, and writes most of them.

It is the tool for changing behaviour you cannot reach any other way — a hard-coded number inside a closure, a flag captured as an upvalue before you loaded.

Reading and rewriting a closure
local function example()
    local threshold = 100
    return function()
        return threshold * 2
    end
end

local inner = example()

-- Read what it closed over, then change it.
for i, value in pairs(debug.getupvalues(inner)) do
    print(i, value)              --> 1  100
end
debug.setupvalue(inner, 1, 5)
print(inner())                   --> 10

-- Constants live separately from upvalues.
print(debug.getconstants(example))

Writing here is unforgiving

debug.setconstant and debug.setstack write into live VM structures. A wrong index or a type mismatch does not error politely — it usually takes the game down. Read the value back before you write over it.

Stack inspection

Constants

Upvalues

Protos

A proto is the compiled prototype of a function defined inside another function. debug.getprotos walks them, which lets you reach a nested closure that was never assigned to anything you can name.

Registry & metatables

The Luau registry holds references the VM itself keeps alive. It is the last resort for finding an object nothing else exposes.