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
};
Related Pages¶
- UE4 Implementation — vtable hooking details
- RPC Parameter Structs — RPC type definitions
- Bridge Internals — framework overview