VINDICTA
Metatable · Function
Bunni.fun
ChocoSploit
Cryptic
Potassium
Seliware
SirHurt
Solara
Velocity
Volcano
Volt
Wave
Xeno

getrawmetatable

Retrieves the actual metatable of any object, bypassing __metatable locks.

function getrawmetatable(object: any): table

Synopsis

How it works

Normally, getmetatable(obj) checks for a __metatable field and returns that decoy instead of the real 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.. getrawmetatable bypasses this by directly reading the internal metatable pointer on the Luau Table or Udata struct, ignoring the __metatable metamethodMetamethodA function in a metatable that overrides default behavior for operations like indexing (__index), assignment (__newindex), calling (__call), comparison (__eq), and arithmetic (__add, __mul, etc.). entirely.

VM internals — struct layout

The 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. pointer lives at a fixed offset in each value's header:
// Table struct (simplified)
typedef struct Table {
  GCObject header;
  uint8_t tmcache;     // tag method cache bits
  uint8_t readonly;    // frozen flag
  uint8_t safeenv;
  uint8_t lsizenode;   // log2(hash part size)
  int sizearray;       // array part length
  TValue* array;       // array part pointer
  LuaNode* node;       // hash part pointer
  Table* metatable;    // ← this is what getrawmetatable reads
} Table;

// Udata struct (userdata, e.g., Instances)
typedef struct Udata {
  GCObject header;
  uint8_t tag;
  int len;             // userdata size
  Table* metatable;    // ← same field for userdata
} Udata;
getrawmetatable reads obj->metatable directly, bypassing the VM's luaT_objtypename guard that checks __metatable.

Shared metatable

All Roblox Instances share a single global 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.. This metatable contains __index, __newindex, __namecall, __tostring, and __eq. Modifying it (after setreadonly(mt, false)) affects every InstanceInstanceThe base class for all Roblox objects (Parts, Models, Scripts, GUIs, etc.). Instances form a tree hierarchy (the DataModel). In Luau, they appear as userdata with shared metatables. in the game. The __metatable field is set to "The metatable is locked" to prevent normal getmetatable() access.

Usage

Unlock and modify a metatable
local mt = getrawmetatable(game)
"cc">-- Make the metatable writable
setreadonly(mt, false)
"cc">-- Now you can replace metamethods
mt.__index = function(self, key)
  print("Property accessed:", key)
  return rawget(mt, key)
end

Parameters

object any
The object to retrieve the raw metatable from.

Returns

table The unguarded metatable of the provided object.