PEX Binary Format¶
Reference for the .pex compiled Papyrus script format as used in Fallout 4 (version 3.9).
All integers are little-endian. All string references are 2-byte indices into the string table.
File Header¶
| Field | Type | Value |
|---|---|---|
| Magic | u32 | 0xFA57C0DE (DE C0 57 FA on disk) |
| Major version | u8 | 3 |
| Minor version | u8 | 9 |
| Game ID | u16 | 2 (Fallout 4) |
| Compile time | u64 | Unix timestamp |
| Source file | strref | e.g. "MyScript.psc" |
| Username | strref | compiler username |
| Machine name | strref | compiler host |
String Table¶
Immediately after the header:
All subsequent strref fields are u16 indices into this table.
Debug Info Block¶
Follows the string table. Skip unless decompiling.
Object Table¶
PexObject (FO4 layout)¶
Important: FO4 adds a constFlag byte between docString and userFlags that Skyrim does not have.
strref name
u32 size ← total object byte size (rarely needed; trust field counts)
strref parentName ← base class, empty if none
strref docString
u8 constFlag ← FO4 ONLY (bit0 = const)
u32 userFlags
strref autoStateName
u16 numStructs
numStructs × PexStruct
u16 numVariables
numVariables × PexVariable
u16 numProperties
numProperties × PexProperty
u16 numStates
numStates × PexState
PexStruct¶
PexStructMember¶
strref name
strref typeName
u32 userFlags
PexValue initialValue
u8 constFlag ← FO4 ONLY
strref docString
PexVariable¶
PexProperty¶
strref name
strref typeName
strref docString
u32 flags ← bit0=readable bit1=writable bit2=autoVar
u32 userFlags
Depending on flags:
- If autoVar: strref autoVarName
- If readable: PexFunction readHandler
- If writable: PexFunction writeHandler
PexState¶
PexFunction¶
strref name
strref returnType
strref docString
u32 userFlags
u8 flags ← bit0=global(static) bit1=native
u16 numParams
numParams × PexFunctionParam
u16 numLocals
numLocals × PexFunctionVar
u16 numInstructions
numInstructions × PexInstruction
PexFunctionParam and PexFunctionVar both have the same layout:
PexInstruction¶
For VarArgs opcodes, the fixed operands include an int count operand followed by count more operands. The reader flattens all operands into a single array.
PexValue¶
A tagged union:
u8 type
0 = None (no extra bytes)
1 = Bool (u8: 0=false 1=true)
2 = Int (i32)
3 = Float (f32)
4 = String (strref)
5 = Identifier (strref)
Type 5 (Identifier) is used for variable references, local names, parameter names. Type 4 (String) is used for literal string values and method/property names in call instructions.
Jump Offset Convention¶
Jump offsets in FO4 are relative to the current instruction index (not the next):
Past-end targets (target >= instruction count) mean "exit function / return nil".