Binary Format

UE4 Binary Property Format

The BinaryData arrays in Mounts.json contain UE4 (Unreal Engine 4) serialized properties in the GVAS format. This page documents the binary layout as reverse-engineered from Icarus save data.

Overview

Each mount's RecorderBlob.BinaryData is a JSON array of unsigned byte values (0–255) that encodes a flat list of named, typed properties. The stream is terminated by a "None" property (a null-terminated string "None\0").

Property Header

Every property begins with:

Offset Size Type Description
0 4 int32 Name string length (including null terminator)
4 N bytes Property name as null-terminated ASCII string
N+4 4 int32 Type string length (including null terminator)
N+8 M bytes Type name as null-terminated ASCII string
N+M+8 4 int32 Data size (bytes of payload following the header)
N+M+12 4 int32 Array index (usually 0)

The terminator property has name "None" with no type or data following.

Property Types

IntProperty

  • Data size: 4
  • Extra header: 1 byte (always 0x00)
  • Payload: 4 bytes, little-endian signed int32

UInt32Property

  • Data size: 4
  • Extra header: 1 byte (always 0x00)
  • Payload: 4 bytes, little-endian unsigned int32

BoolProperty

  • Data size: 0 (value is in the header!)
  • Extra header: 1 byte — the boolean value (0x00 = False, 0x01 = True)
  • Payload: none

StrProperty

  • Data size: varies
  • Extra header: 1 byte (always 0x00)
  • Payload: 4-byte signed int32 length prefix + null-terminated string. Encoding depends on the sign:
  • Positive length → UTF-8 string, null terminator is 1 byte (\x00)
  • Negative length → UTF-16 LE string, null terminator is 2 bytes (\x00\x00). The absolute value = character count.
  • Zero length → empty string (no bytes follow)

UE4 uses negative length / UTF-16 LE automatically for strings containing non-ASCII characters (e.g., accented French names like "mâle alpha"). ASCII-only strings always use positive length / UTF-8.

NameProperty

  • Same layout as StrProperty

EnumProperty

  • Extra header before payload:
  • 4-byte length + null-terminated enum type name (e.g., "EMountCombatBehaviourState\0")
  • 1 byte (always 0x00)
  • Payload: 4-byte length + null-terminated enum value string (e.g., "EMountCombatBehaviourState::AggressiveEngagement\0")

StructProperty

  • Extra header before payload:
  • 4-byte length + null-terminated struct type name (e.g., "Transform\0", "IcarusCharacterRecord\0")
  • 16 bytes — struct GUID (usually all zeros)
  • 1 byte (always 0x00)
  • Payload: Depends on struct type:
  • Simple structs (Quat, Vector, Guid, LinearColor): raw packed data
    • Quat: 4 × float64 (32 bytes) — X, Y, Z, W
    • Vector: 3 × float64 (24 bytes) — X, Y, Z
    • Guid: 16 bytes — A, B, C, D as uint32
    • LinearColor: 4 × float32 (16 bytes) — R, G, B, A
  • Complex structs (Transform, IcarusCharacterRecord, etc.): nested property list terminated by "None"

ArrayProperty

  • Extra header before payload:
  • 4-byte length + null-terminated inner type name (e.g., "StructProperty\0", "IntProperty\0")
  • 1 byte (always 0x00)
  • Payload: starts with 4-byte int32 element count, then:
  • Simple arrays (IntProperty, StrProperty, etc.): sequential values
  • Struct arrays: additional metadata before elements:
    • Field name (length-prefixed string)
    • Type name "StructProperty\0"
    • Total data size (int32 + padding int32)
    • Struct type name (length-prefixed string)
    • 16-byte GUID
    • 1 byte separator
    • Then N elements, each a nested property list terminated by "None"

Terminator

The property list ends when a property name of "None" is encountered. This is encoded as:

05 00 00 00  4E 6F 6E 65 00

(length=5, "None\0")

Example: IntProperty

For Experience = 41459:

0B 00 00 00                          # name length = 11
45 78 70 65 72 69 65 6E 63 65 00     # "Experience\0"
0C 00 00 00                          # type length = 12
49 6E 74 50 72 6F 70 65 72 74 79 00  # "IntProperty\0"
04 00 00 00                          # data size = 4
00 00 00 00                          # array index = 0
00                                   # extra byte
F3 A1 00 00                          # value = 41459 (little-endian)

Known Value Mappings

Some IntProperty fields use specific value mappings:

Field Value Meaning
Sex 1 Female
Sex 2 Male
Sex 0 ⚠️ Invalid (game defaults to Female)

See Species & Types — Gender / Sex Values for details.

Notes

  • All strings are null-terminated and their length includes the null byte
  • All integers are little-endian
  • The "data size" field does NOT include the extra header bytes (enum type name, struct metadata, etc.) — it only counts the actual payload
  • BoolProperty is unique: its value lives in the extra header byte, and data size is 0
  • The format is recursive: structs contain property lists, which can contain more structs

See also: Architecture — Data Flow · Talent & Genetics Data — Storage Format · Species & Types — Save Data Fields

Back to Docs