Skip to content

Memory Offsets & Hooks

Memory layout definitions and hook points for the HumanitZ UE4 4.27 game server. These offsets are version-specific and must be updated when the game updates.


Overview

The bridge reads game state by directly accessing memory at known offsets within UE4 objects. This approach avoids the overhead of UE4's reflection system for hot-path reads (player positions, health, etc.) while using introspection for less frequent operations.

Offset Discovery

Offsets are discovered through two methods:

Method When Used How
Runtime introspection First load, property name changes Walk FProperty chain via UE4 reflection
Hardcoded offsets Hot-path reads (per-tick) Cached in header files, verified at init
// At init time, verify hardcoded offsets match runtime values
void verify_offsets() {
    assert(find_property_offset(ACharacter::StaticClass(), "Health")
           == OFFSET_CHARACTER_HEALTH);
    // If assertion fails, game updated — need new offsets
}

HumanitZ Game Module Hooks

RPC Hooks (42+)

The HumanitZ module hooks 42+ UE4 server RPCs:

RPC Name Bridge Handler STDB Reducer
SERVER_DamagePlayer hz_rpcs.cpp damage_player
SERVER_PlayerMoved hz_position_sampler.cpp update_position (batched)
SERVER_CraftItem hz_rpcs.cpp craft_item
SERVER_PlaceBuilding hz_rpcs.cpp place_building
SERVER_TakeItem hz_rpcs.cpp container_take_items
SERVER_DepositItem hz_rpcs.cpp container_deposit
SERVER_UseItem hz_rpcs.cpp use_item
SERVER_EquipItem hz_rpcs.cpp equip_item
SERVER_DestroyBuilding hz_rpcs.cpp destroy_building
SERVER_SpawnVehicle hz_rpcs.cpp spawn_vehicle
SERVER_RepairVehicle hz_rpcs.cpp repair_vehicle
SERVER_SendChat hz_rpcs.cpp send_chat
SERVER_CreateFaction hz_rpcs.cpp create_faction
SERVER_JoinFaction hz_rpcs.cpp join_faction
... ... ...

Worker Threads

Thread Frequency Reads Writes
AI Thread 2 Hz Zombie positions, player positions zombie_position, zombie_ai reducers
World Thread 2 Hz Building state, vehicle state, containers update_world_state reducer
Budget Thread 2 Hz Actor counts, frame time, memory server_heartbeat reducer
Events Thread 1 Hz Game events, security events log_event, log_security reducers

Position Sampler

The position sampler (hz_position_sampler.cpp) batches player position updates:

Per tick: Read player positions from memory
Accumulate in buffer (up to 10 Hz)
Every 100ms: Batch all changed positions into single reducer call
STDB: update_position(player_id, x, y, z, yaw)

Spatial Resubscription

The spatial system (hz_spatial.cpp) manages chunk-based subscriptions:

World divided into chunks (e.g., 1000×1000 units)
Track which chunks have active players
Subscribe to STDB for entities in active chunks only
On player movement: resubscribe if chunk changed

Schema Generation

codegen.py generates 218 C++ header files from UE4 type definitions:

Output Count Content
schema/reducers/ 111 Reducer parameter structs + BSATN serialisation
schema/types/ 58 Custom type definitions
schema/tables/ 44 Table row structs + deserialisation
Top-level 5 all_reducers.h, all_types.h, all_tables.h, table_names.h, table_dispatch.h

Table Dispatch

// schema/table_dispatch.h
using TableDeserializer = std::function<void(BsatnReader&)>;

std::unordered_map<std::string, TableDeserializer> table_dispatch = {
    {"player_position", [](BsatnReader& r) { auto row = PlayerPosition::deserialize(r); /* handle */ }},
    {"player_vitals",   [](BsatnReader& r) { auto row = PlayerVitals::deserialize(r);   /* handle */ }},
    // ... 44 tables
};