getscriptbytecode
Extracts the raw compiled Luau bytecode from a Script instance.
function getscriptbytecode(script: Instance): stringSynopsis
How it works
Reads the compiled Luau bytecodeBytecodeThe compiled binary representation of Luau source code. A sequence of 32-bit instructions (opcodes + operands) stored in a Proto's code[] array. Executed by the Luau VM interpreter. directly from the Script instance's internal
ProtectedString source property. The returned binary string contains the full bytecode blob including the header, string table, instruction stream, and proto definitions.Bytecode format
The Luau bytecodeBytecodeThe compiled binary representation of Luau source code. A sequence of 32-bit instructions (opcodes + operands) stored in a Proto's code[] array. Executed by the Luau VM interpreter. binary is structured as:
Offset Field
────── ─────────────────────────
[0] Version byte (currently 6)
[1] Types version
[2..n] String table (varint count + length-prefixed strings)
[n+1..] Proto array (varint count, then each Proto):
maxstacksize : uint8
numparams : uint8
nups : uint8
isvararg : uint8
flags : uint8
sizecode : varint (instruction count)
instructions[]: uint32 each
sizek : varint (constant count)
constants[] : typed TValue entries
sizep : varint (child proto count)
protos[] : varint indices into proto array
[end] Main proto index (varint)
Each instruction is a 32-bit word. The opcode is in bits [0:7]. Operand encoding varies by opcode type (iABCiABC encodingInstruction format with three operands: A (8 bits), B (8 bits), C (8 bits) packed into a 32-bit word alongside the opcode (8 bits). Used by CALL, RETURN, MOVE, GETTABLE, SETTABLE, etc., iABxiABx encodingInstruction format with two operands: A (8 bits) and Bx (16 bits, unsigned). Used when a larger operand is needed — LOADK R(A), K(Bx) and CLOSURE R(A), P(Bx) use this format., iAsBxiAsBx encodingInstruction format with a signed operand: A (8 bits) and sBx (16 bits, signed with bias). Used for jump offsets — JUMP and conditional branches encode the PC delta in sBx.). Some opcodes use a 32-bit AUX word immediately after.Common opcodes
| Opcode | Encoding | Description |
|---|---|---|
LOADK | iABxiABx encodingInstruction format with two operands: A (8 bits) and Bx (16 bits, unsigned). Used when a larger operand is needed — LOADK R(A), K(Bx) and CLOSURE R(A), P(Bx) use this format. | Load constant K(Bx) into R(A) |
GETGLOBAL | iABx+AUXAUX wordAn auxiliary 32-bit word that follows certain Luau instructions (NAMECALL, GETGLOBAL, GETTABLEKS, etc.) to provide an extra operand — typically a constant table index for string keys. | R(A) = env[K(AUX)] |
NAMECALL | iABCiABC encodingInstruction format with three operands: A (8 bits), B (8 bits), C (8 bits) packed into a 32-bit word alongside the opcode (8 bits). Used by CALL, RETURN, MOVE, GETTABLE, SETTABLE, etc.+AUX | R(A) = R(B):K(AUX) method lookup |
CALL | iABC | Call R(A) with B-1 args, C-1 returns |
CLOSURE | iABx | Create closureClosureA function value that captures its lexical environment. In Luau, closures come in two types: LClosure (Luau bytecode + Proto + upvalues) and CClosure (native C function pointer + upvalues). from ProtoProtoThe bytecode prototype structure. Contains compiled instructions (code[]), constants (k[]), child protos (p[]), debug info, parameter count, upvalue count, and other metadata for a Luau function.[Bx] |
RETURN | iAB | Return R(A)..R(A+B-2) |
Usage
Dump bytecode to output
local script = game.Players.LocalPlayer.PlayerScripts:FindFirstChild("MainScript")
if script then
local bytecode = getscriptbytecode(script)
print("Bytecode length:", #bytecode)
endParameters
script Instance A LocalScript or ModuleScript instance from the DataModel.
Returns
string A raw binary string containing the compiled Luau bytecode.
Decompilation
The returned bytecode is compatible with tools like unluac or luadec when the raw bytes are written to a file. The bytecode header identifies the Luau version used to compile the script.