9  Appendix A: SDK Class Layouts

This appendix provides detailed memory layouts for BL4’s core classes, extracted from SDK analysis. These are essential for memory hacking, cheat development, or deep reverse engineering.


9.1 Core UE5 Types

9.1.1 FName (8 bytes)

struct FName {
    int32_t ComparisonIndex;  // 0x00 - Index into GNames pool
    int32_t Number;           // 0x04 - Instance number (e.g., "Actor_5")
};

9.1.2 FVector (24 bytes)

struct FVector {
    double X;  // 0x00
    double Y;  // 0x08
    double Z;  // 0x10
};
Warning

UE5 uses double (8 bytes) for vectors, not float like UE4. This is a common source of offset calculation errors.

9.1.3 FRotator (24 bytes)

struct FRotator {
    double Pitch;  // 0x00
    double Yaw;    // 0x08
    double Roll;   // 0x10
};

9.1.4 FQuat (32 bytes)

struct FQuat {
    double X;  // 0x00
    double Y;  // 0x08
    double Z;  // 0x10
    double W;  // 0x18
};

9.1.5 FTransform (96 bytes)

struct FTransform {
    FQuat Rotation;       // 0x00 (32 bytes)
    FVector Translation;  // 0x20 (24 bytes)
    char pad[8];          // 0x38
    FVector Scale3D;      // 0x40 (24 bytes)
    char pad[8];          // 0x58
};  // Total: 0x60

9.1.6 TArray (16 bytes)

template<typename T>
struct TArray {
    T* Data;          // 0x00 - Pointer to element array
    int32_t Count;    // 0x08 - Current element count
    int32_t Max;      // 0x0C - Allocated capacity
};

9.1.7 FString (16 bytes)

struct FString {
    wchar_t* Data;    // 0x00 - Wide string pointer
    int32_t Count;    // 0x08 - String length
    int32_t Max;      // 0x0C - Buffer capacity
};

9.2 UObject Hierarchy

9.2.1 UObject (40 bytes)

The base class for all Unreal objects.

class UObject {
    void* VTable;             // 0x00 - Virtual function table
    int32_t ObjectFlags;      // 0x08 - RF_* flags
    int32_t InternalIndex;    // 0x0C - Index in GUObjectArray
    UClass* ClassPrivate;     // 0x10 - Pointer to this object's class
    FName NamePrivate;        // 0x18 - Object's name
    UObject* OuterPrivate;    // 0x20 - Parent/container object
};  // Total: 0x28
Offset Size Field Purpose
0x00 8 VTable Points to virtual function table
0x08 4 ObjectFlags Object state flags
0x0C 4 InternalIndex Position in GUObjectArray
0x10 8 ClassPrivate Pointer to UClass
0x18 8 NamePrivate FName (index + number)
0x20 8 OuterPrivate Package/container pointer

9.2.2 UField (48 bytes)

class UField : public UObject {
    UField* Next;  // 0x28 - Next field in chain
};

9.2.3 UStruct (176 bytes)

class UStruct : public UField {
    char pad[16];              // 0x30
    UStruct* SuperStruct;      // 0x40 - Parent class/struct
    UField* Children;          // 0x48 - First child field (legacy)
    FField* ChildProperties;   // 0x50 - Property linked list (UE5)
    int32_t PropertiesSize;    // 0x58 - Total size of properties
    int16_t MinAlignment;      // 0x5C
    char pad[82];              // 0x5E
};  // Total: 0xB0

9.2.4 UClass (512 bytes)

class UClass : public UStruct {
    char pad[96];              // 0xB0
    UObject* ClassDefaultObject;  // 0x110 - CDO pointer
    char pad[232];             // 0x118
};  // Total: 0x200

9.3 Actor Hierarchy

9.3.1 AActor (912 bytes)

class AActor : public UObject {
    char pad[416];                    // 0x28
    USceneComponent* RootComponent;   // 0x1C8
    char pad[448];                    // 0x1D0
};  // Total: 0x390

9.3.2 APawn (1040 bytes)

class APawn : public AActor {
    char pad[32];                // 0x390
    APlayerState* PlayerState;   // 0x3B0
    char pad[8];                 // 0x3B8
    AController* Controller;     // 0x3C0
    char pad[72];                // 0x3C8
};  // Total: 0x410

9.3.3 ACharacter (1864 bytes)

class ACharacter : public APawn {
    char pad[24];                              // 0x410
    USkeletalMeshComponent* Mesh;              // 0x428
    UCharacterMovementComponent* Movement;     // 0x430
    char pad[784];                             // 0x438
};  // Total: 0x748

9.4 Controller Classes

9.4.1 AController (1064 bytes)

class AController : public AActor {
    char pad[8];                  // 0x390
    APlayerState* PlayerState;    // 0x398
    char pad[48];                 // 0x3A0
    APawn* Pawn;                  // 0x3D0
    char pad[8];                  // 0x3D8
    ACharacter* Character;        // 0x3E0
    char pad[64];                 // 0x3E8
};  // Total: 0x428

9.4.2 APlayerController (2392+ bytes)

class APlayerController : public AController {
    char pad[16];                           // 0x428
    APawn* AcknowledgedPawn;                // 0x438
    char pad[8];                            // 0x440
    APlayerCameraManager* CameraManager;    // 0x448
    char pad[168];                          // 0x450
    UCheatManager* CheatManager;            // 0x4F8
    UClass* CheatClass;                     // 0x500
    char pad[1104];                         // 0x508
};  // Total: 0x958+

9.5 BL4/Oak Classes

9.5.1 AGbxPlayerController (3496 bytes)

class AGbxPlayerController : public APlayerController {
    char pad[176];                        // 0x958
    ACharacter* PrimaryCharacter;         // 0xA08
    char pad[536];                        // 0xA10
    bool bUseGbxCurrencyManager;          // 0xC28
    char pad[7];                          // 0xC29
    UGbxCurrencyManager* CurrencyManager; // 0xC30
    char pad[288];                        // 0xC38
    bool bUseRewardsManager;              // 0xD58
    char pad[7];                          // 0xD59
    UGbxRewardsManager* RewardsManager;   // 0xD60
    char pad[64];                         // 0xD68
};  // Total: 0xDA8

9.5.2 AOakPlayerController (15424 bytes)

class AOakPlayerController : public AGbxPlayerController {
    char pad[376];                    // 0xDA8
    AOakCharacter* OakCharacter;      // 0xF20
    char pad[8880];                   // 0xF28
    bool bIsCurrentlyTargeted;        // 0x31D8
    char pad[48];                     // 0x31D9
    bool bFullyAimingAtTarget;        // 0x3209
    // ... more fields
};  // Total: 0x3C40

9.5.3 AGbxCharacter (15232 bytes)

class AGbxCharacter : public ACharacter {
    char pad[13368];  // 0x748
};  // Total: 0x3B80

9.5.4 AOakCharacter (38800 bytes)

The main player/enemy character class. This is one of the largest classes in the game.

class AOakCharacter : public AGbxCharacter {
    char pad[1208];                           // 0x3B80
    FOakDamageState DamageState;              // 0x4038 (size: 0x608)
    FOakCharacterHealthState HealthState;     // 0x4640 (size: 0x1E8)
    char pad[4976];                           // 0x4828
    ECharacterHealthCondition HealthCondition; // 0x5B98
    char pad[951];                            // 0x5B99
    FOakActiveWeaponsState ActiveWeapons;     // 0x5F50 (size: 0x210)
    char pad[960];                            // 0x6160
    FDownState DownState;                     // 0x6F40 (size: 0x398)
    char pad[8];                              // 0x72D8
    AOakCharacter* ActorBeingRevived;         // 0x72E0
    // ... many more fields
    FGbxAttributeFloat AmmoRegenerate;        // 0x95E8
};  // Total: 0x9790

Key offsets for AOakCharacter:

Offset Size Field Description
0x4038 0x608 DamageState Damage tracking state
0x4640 0x1E8 HealthState Health/shield values
0x5B98 1 HealthCondition Healthy/Injured/Dead enum
0x5F50 0x210 ActiveWeapons Equipped weapon state
0x6F40 0x398 DownState FFYL state
0x72E0 8 ActorBeingRevived Revive target pointer

9.6 Inventory Classes

9.6.1 AInventory (2224 bytes)

class AInventory : public AActor {
    char pad[1312];  // 0x390
};  // Total: 0x8B0

9.6.2 AWeapon (3400 bytes)

class AWeapon : public AInventory {
    char pad[912];                           // 0x8B0
    FDamageModifierData DamageModifierData;  // 0xC40 (size: 0x6C)
    char pad[12];                            // 0xCAC
    FGbxAttributeFloat ZoomTimeScale;        // 0xCB8
    char pad[132];                           // 0xCC4
};  // Total: 0xD48

9.7 Currency System

9.7.1 FSToken (12 bytes)

struct FSToken {
    int32_t Hash;  // 0x00 - Token hash
    FName Name;    // 0x04 - Token name
};

9.7.2 FGbxCurrency (24 bytes)

struct FGbxCurrency {
    FSToken Token;   // 0x00
    char pad[4];     // 0x0C
    uint64_t Amount; // 0x10 - Currency amount
};

9.7.3 UGbxCurrencyManager (64 bytes)

class UGbxCurrencyManager : public UObject {
    char pad[8];                      // 0x28
    TArray<FGbxCurrency> Currencies;  // 0x30
};

Currency indices:

Index Currency
0 Cash
1 Eridium
2 Gold Keys
3 Unknown

9.8 Attribute Types

9.8.1 FGbxAttributeFloat (12 bytes)

struct FGbxAttributeFloat {
    char pad[4];       // 0x00
    float Value;       // 0x04 - Current value
    float BaseValue;   // 0x08 - Base value before modifiers
};

9.8.2 FGbxAttributeInteger (12 bytes)

struct FGbxAttributeInteger {
    char pad[4];        // 0x00
    int32_t Value;      // 0x04
    int32_t BaseValue;  // 0x08
};

9.9 Enums

9.9.1 ECharacterHealthCondition

enum class ECharacterHealthCondition : int8_t {
    Healthy = 0,
    Injured = 1,
    Dead = 2
};

9.9.2 EMovementMode

enum class EMovementMode : int8_t {
    MOVE_None = 0,
    MOVE_Walking = 1,
    MOVE_NavWalking = 2,
    MOVE_Falling = 3,
    MOVE_Swimming = 4,
    MOVE_Flying = 5,
    MOVE_Custom = 6,
    MOVE_MAX = 7
};

9.10 Global Pointers

These offsets are from the PE image base (0x140000000):

Global Offset Virtual Address Description
GUObjectArray 0x113878f0 0x1513878f0 All UObjects
GNames 0x112a1c80 0x1512a1c80 FName string pool
GWorld 0x11532cb8 0x151532cb8 Current world
ProcessEvent 0x14f7010 0x144f7010 Event dispatcher
Note

These offsets are from the November 2025 patch. Earlier versions had offsets 0x1000 lower.


9.11 Pattern Signatures

For finding globals via code scanning:

GNames:   48 8D 0D ? ? ? ? E8 ? ? ? ? C6 05 ? ? ? ? ? 8B 05
GObjects: 48 8B 15 ? ? ? ? C1 E8 ? 48 8D 0C 49 C1 E1 ? 48 03
GWorld:   48 8B 05 ? ? ? ? 48 89 44 24 ? 48 8D 54 24 ? 4C 8D

The ? bytes are wildcards. Calculate target address from RIP-relative offset in the instruction.


9.12 Mesh & Visibility

Component Offset Field Description
Mesh + 0x39C LastSubmitTime Last frame submitted
Mesh + 0x3A0 LastRenderTimeOnScreen Last visible frame

Visibility check: If LastSubmitTime > LastRenderTimeOnScreen, the mesh was occluded (behind a wall).


9.13 FProperty Layout

For parsing reflection data:

// FField base (shared by all field types)
struct FField {
    void* VTable;           // 0x00
    UStruct* Owner;         // 0x08
    FField* Next;           // 0x10
    FName NamePrivate;      // 0x18
    uint32_t FlagsPrivate;  // 0x20
};

// FProperty extends FField
struct FProperty : FField {
    int32_t ArrayDim;       // 0x28 - Array size (1 for non-arrays)
    int32_t ElementSize;    // 0x2C - Size of one element
    uint64_t PropertyFlags; // 0x30 - CPF_* flags
    uint16_t RepIndex;      // 0x38
    char pad[2];            // 0x3A
    int32_t Offset_Internal;// 0x3C - Byte offset in struct
    // Type-specific data at 0x40+
};

These layouts are from SDK dumps as of November 2025. Offsets may change with game patches.