World Executor · Roblox VM

Metatable

Read and patch raw metatables, toggle table read-only state, and read or rewrite the namecall target while inside a hook.

Overview

Every Roblox instance shares one metatable, and that metatable is locked read-only. Unlock it and you control what happens on every property read, every property write and every method call in the game.

__namecall is the important one. Roblox compiles object:Method(args) into a single namecall rather than an index-then-call, so a single hook there sees every method invocation — including FireServer and InvokeServer.

The classic namecall hook
local metatable = getrawmetatable(game)
local wasReadOnly = isreadonly(metatable)
setreadonly(metatable, false)

local old = metatable.__namecall
metatable.__namecall = newcclosure(function(self, ...)
    if getnamecallmethod() == "FireServer" and not checkcaller() then
        print("fired:", self:GetFullName(), ...)
    end
    return old(self, ...)
end)

setreadonly(metatable, wasReadOnly)

hookmetamethod does the unlock, swap and re-lock in one call and is what you should reach for in practice. The manual version above is worth reading once so the shorthand makes sense.

Namecall

Raw metatables

Read-only state

Metamethods

A reference for which metamethod fires on which operation. These are notes rather than callable functions — they describe what you are hooking into.