setreadonly
Sets or clears the read-only (frozen) flag on a table.
function setreadonly(t: table, value: boolean): ()Synopsis
How it works
Directly sets or clears the
readonly flag on a Luau table header. When called with false, the table becomes writable again even if Roblox had frozen it. This is essential for modifying locked tables such as global environmentGlobal environment (genv)The executor's global environment table — the _G-equivalent for executor-loaded scripts. Functions set here (via getgenv()) are accessible from any executor script but invisible to game scripts. tables or shared metatablesMetatableA table attached to another table (or userdata) that defines operator overloading via metamethods (__index, __newindex, __call, etc.). Roblox Instances use shared read-only metatables for method dispatch..Common pattern
To modify a locked metatableMetatableA table attached to another table (or userdata) that defines operator overloading via metamethods (__index, __newindex, __call, etc.). Roblox Instances use shared read-only metatables for method dispatch.:
local mt = getrawmetatable(game)
local old = mt.__index
setreadonly(mt, false)
mt.__index = newindex_hook
setreadonly(mt, true)
Always re-lock the table after modification to avoid detection by anti-cheatAnti-cheatGame-side Luau scripts designed to detect and prevent exploitation. Common checks: verifying closure types (iscclosure), checking metatable integrity, monitoring remote call patterns, and scanning for known executor globals. scripts that call isreadonly().Usage
Unfreeze a game metatable
local mt = getrawmetatable(game)
setreadonly(mt, false)
mt.__tostring = function() return "Hacked!" end
setreadonly(mt, true)
print(tostring(game)) "cc">--> Hacked!Parameters
t table The table to modify.
value boolean true to freeze, false to unfreeze.