Skip to content

RPC Parameter Structs

When UE4 calls ProcessEvent, parameters are passed as a raw void* pointer to a struct. This page documents the parameter structs for HumanitZ RPCs that the bridge intercepts.


Overview

UE4 RPCs pass parameters via a packed struct allocated on the stack. The bridge must know the exact memory layout of each struct to extract parameter values. These are defined in games/humanitz/include/hz_parms.h.

Parameter Struct Convention

// UE4 RPC parameter structs follow this pattern:
struct FunctionName_Parms {
    ParamType1 param1;
    ParamType2 param2;
    // ... in declaration order
    // Return value (if any) is the last field
};

Key Parameter Structs

Player Damage

struct SERVER_DamagePlayer_Parms {
    FString TargetPlayerId;    // Steam ID of the target
    float DamageAmount;        // Raw damage value
    uint8_t DamageType;        // 0=Melee, 1=Ranged, 2=Explosive, etc.
    FString AttackerPlayerId;  // Steam ID of the attacker (empty for environment)
    FVector HitLocation;       // World-space impact point
    FVector HitNormal;         // Impact surface normal
};

Player Movement

struct SERVER_PlayerMoved_Parms {
    FVector Location;          // World position (X, Y, Z)
    FRotator Rotation;         // View rotation (Pitch, Yaw, Roll)
    float Velocity;            // Current speed
    uint8_t MovementMode;      // 0=Walking, 1=Swimming, 2=Flying, etc.
};

Crafting

struct SERVER_CraftItem_Parms {
    int32_t RecipeId;          // Recipe table index
    int32_t Quantity;          // Number to craft
    FString CraftingStationId; // Empty if hand-crafting
};

Building Placement

struct SERVER_PlaceBuilding_Parms {
    int32_t BuildingTypeId;    // Building type enum
    FVector Location;          // Placement world position
    FRotator Rotation;         // Placement rotation
    FString PlayerId;          // Builder's Steam ID
};

Container Interaction

struct SERVER_TakeItem_Parms {
    FString ContainerId;       // Container unique ID
    int32_t SlotIndex;         // Slot to take from
    int32_t Quantity;          // Amount to take
    FString PlayerId;          // Player taking the item
};

struct SERVER_DepositItem_Parms {
    FString ContainerId;       // Container unique ID
    int32_t ItemId;            // Item type ID
    int32_t Quantity;          // Amount to deposit
    int32_t SlotIndex;         // Target slot (-1 for auto)
    FString PlayerId;          // Player depositing
};

Chat

struct SERVER_SendChat_Parms {
    FString Message;           // Chat text
    uint8_t Channel;           // 0=Global, 1=Team, 2=Local, 3=Whisper
    FString TargetPlayerId;    // Whisper target (empty for non-whisper)
};

Faction

struct SERVER_CreateFaction_Parms {
    FString FactionName;       // Display name
    uint8_t FactionColour;     // Team colour index
    FString Description;       // Optional description
};

struct SERVER_JoinFaction_Parms {
    FString FactionId;         // Faction unique ID
    FString PlayerId;          // Joining player's Steam ID
};

Vehicle

struct SERVER_SpawnVehicle_Parms {
    int32_t VehicleTypeId;     // Vehicle type enum
    FVector Location;          // Spawn position
    FRotator Rotation;         // Spawn rotation
};

struct SERVER_RepairVehicle_Parms {
    FString VehicleId;         // Vehicle unique ID
    int32_t RepairAmount;      // Repair points applied
    FString PlayerId;          // Repairing player
};

Extracting Parameters

void on_damage_rpc(void* params_ptr) {
    auto* parms = static_cast<SERVER_DamagePlayer_Parms*>(params_ptr);

    std::string target = fstring_to_std(parms->TargetPlayerId);
    float damage = parms->DamageAmount;
    uint8_t type = parms->DamageType;

    // Call STDB reducer
    stdb_conn->call_reducer("damage_player", [&](BsatnWriter& w) {
        w.write_string(target);
        w.write_f32(damage);
        w.write_u8(type);
    });
}

FString Conversion

UE4 FString uses wide characters (UTF-16 on Windows, UTF-32 on Linux). The bridge converts to UTF-8:

std::string fstring_to_std(const FString& fstr) {
    if (!fstr.Data || fstr.Count <= 0) return "";
    // On Linux UE4, TCHAR is char (UTF-8)
    return std::string(fstr.Data, fstr.Count - 1);  // -1 for null terminator
}

Alignment and Packing

UE4 parameter structs follow the platform's default alignment rules:

Type Size Alignment
float 4 4
int32_t 4 4
uint8_t 1 1
FVector 12 4
FRotator 12 4
FString 16 (x64) 8
TArray<T> 16 (x64) 8

⚠️ Padding may be inserted between fields. When in doubt, use offsetof() or runtime introspection to verify field offsets.