Metatable
Read and patch raw metatables, toggle table read-only state, and read or rewrite the namecall target while inside a hook.
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.
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.
A reference for which metamethod fires on which operation. These are notes rather than callable functions — they describe what you are hooking into.