Base Types

The base types that can be read from the bitstream. We have provided sample pseudocode for each type, in which we assume a predefined function read(bits) that reads a number of bits from the bitstream.

Table of Contents

Basic

bit_bool

A boolean value, encoded as a single bit.

FUNCTION bit_bool:
    RETURN read(1) > 0

Integers

bit_varuint_32

A 32-bit unsigned integer, encoded as a protobuf style varint.

FUNCTION bit_varuint_32:
    value = 0
    offset = 0
    // A 32-bit varint is at most 5 bytes long. 5 * 7 = 35.
    // This while loop is a safeguard against reading too many bytes.
    WHILE offset != 35:
        byte = read(8)
        // Add the lower 7 bits of the byte to the result.
        value = value | ((byte & 0x7F) << offset)
        offset = offset + 7
        // If the most significant bit is 0, we're done.
        IF (byte & 0x80) == 0:
            BREAK
    RETURN value

bit_varint_32

A 32-bit signed integer, encoded as a protobuf style varint.

FUNCTION bit_varint_32:
    // First, decode as an unsigned integer.
    unsigned_value = bit_varuint_32(reader)
    // Then, perform ZigZag decoding.
    value = unsigned_value >> 1
    IF (unsigned_value & 1) != 0:
        value = NOT value // or -(value + 1)
    RETURN value

bit_varuint_64

A 64-bit unsigned integer, encoded as a protobuf style varint.

FUNCTION bit_varuint_64:
    value = 0
    offset = 0
    index = 0
    LOOP:
        byte = read(8)
        // If the most significant bit is 0, this is the last byte.
        IF byte < 0x80:
            // Check for overflow. A 64-bit varint is at most 10 bytes.
            IF index > 9 OR (index == 9 AND byte > 1):
                THROW VarintOverflowError
            RETURN value | (byte << offset)
        
        // Add the lower 7 bits to the result.
        value = value | ((byte & 0x7F) << offset)
        offset = offset + 7
        index = index + 1

bit_varint_64

A 64-bit signed integer, encoded as a protobuf style varint.

FUNCTION bit_varint_64:
    // First, decode as an unsigned integer.
    unsigned_value = bit_varuint_64(reader)
    // Then, perform ZigZag decoding.
    value = unsigned_value >> 1
    IF (unsigned_value & 1) != 0:
        value = NOT value // or -(value + 1)
    RETURN value

bit_uint64_le

An 64-bit unsigned integer, encoded as a fixed 64-bit value in little-endian format.

FUNCTION bit_uint64_le:
    bytes = read(64)
    RETURN u64_from_le_bytes(bytes)

bit_bitvar_uint

A 32-bit unsigned integer, encoded as follows:

  • The first 4 bits are the MSB of the value.
  • The next 2 bits determine how many more bits to read.
  • The remaining bits are the LSB of the value.
FUNCTION bit_ubitvar:
    // Read the first 6 bits.
    value = read(6)
    
    // The next 2 bits determine how many more bits to read.
    SWITCH (value & 0x30):
        // 01: read another 4 bits
        CASE 16:
            RETURN (value & 15) | (read(4) << 4)
        // 10: read another 8 bits
        CASE 32:
            RETURN (value & 15) | (read(8) << 4)
        // 11: read another 28 bits
        CASE 48:
            RETURN (value & 15) | (read(28) << 4)
        // 00: the value is just the first 6 bits
        DEFAULT:
            RETURN value

bit_fieldpath_uint

A 32-bit unsigned integer, encoded in huffman style:

  • When <1> then read 2 bits
  • When <01> then read 4 bits
  • When <001> then read 10 bits
  • When <0001> then read 17 bits
  • When <0000> then read 31 bits

This type is used for field paths.

FUNCTION bit_fieldpath_int:
    // This encoding uses a series of single-bit flags
    // to determine the number of bits to read for the value.
    IF bit_bool() == true:
        RETURN read(2)
    
    IF bit_bool() == true:
        RETURN read(4)
        
    IF bit_bool() == true:
        RETURN read(10)
        
    IF bit_bool() == true:
        RETURN read(17)
        
    RETURN read(31)

bit_component_uint

A 32-bit unsigned integer, encoded as a single bit.

FUNCTION unsigned_integer_component:
    // The value is simply a single bit.
    RETURN read(1)

Floating-Point

bit_float32

A 32-bit floating-point number, encoded as a fixed 32-bit value in little-endian format.

FUNCTION bit_float32:
    bytes = read(32)
    // Read bytes as a little-endian unsigned integer.
    le_uint = u32_from_le_bytes(bytes)
    // Reinterpret the integer bits as a float.
    RETURN f32_from_bits(le_uint)

bit_float32_coord

A 32-bit floating-point number representing a coordinate. It's encoded with flags for the presence of integer and fractional parts, allowing for variable precision.

FUNCTION bit_float32_coord:
    // Read flags to see if integer and fractional parts exist
    has_integer_part = read(1)
    has_fractional_part = read(1)

    // If neither part exists, the value is zero
    IF has_integer_part == 0 AND has_fractional_part == 0:
        RETURN 0.0

    // Read the sign of the float
    is_negative = bit_bool()

    integer_value = 0
    IF has_integer_part == 1:
        // Read the 14-bit integer part
        integer_value = read(14) + 1
    
    fractional_value = 0
    IF has_fractional_part == 1:
        // Read the 5-bit fractional part
        fractional_value = read(5)

    // Combine the parts. The fractional part is divided by 2^5 (32)
    value = integer_value + fractional_value / 32.0

    IF is_negative == TRUE:
        value = -value

    RETURN value

bit_normal

A 32-bit floating-point number representing a normal vector component, encoded in 11 bits plus a sign bit.

FUNCTION bit_float32_normal:
    is_negative = bit_bool()
    length = read(11)

    // This maps the 11-bit integer to a float range.
    value = length * (1.0 / 2048.0 - 1.0)
    
    IF is_negative:
        RETURN -value
    ELSE:
        RETURN value

bit_float32_noscale

A standard 32-bit IEEE float, read directly from the bitstream without any scaling.

FUNCTION bit_float32_noscale:
    bits = read(32)
    // Reinterpret the integer bits as a float
    RETURN f32_from_bits(bits)

bit_float32_angle

An angle in degrees, encoded in a variable number of bits. The raw integer value is normalised to the [0, 360) range.

FUNCTION bit_float32_angle(bits):
    raw_value = read(bits)
    // Normalize the raw integer to the range [0, 360)
    divisor = 2^bits
    angle = raw_value * 360.0 / divisor
    RETURN angle

bit_float32_angle_precise

A precise angle, encoded as a 20-bit bit_float32_angle, then mapped to the [-180, 180) range

FUNCTION bit_float32_angle(bits):
    RETURN bit_float32_angle(20) - 180.0

Angles

bit_qangle_precise

A 3-component angle vector, where each component is a bit_float32_angle_precise. Each component is prefixed with a boolean flag indicating if it's present.

FUNCTION bit_qangle_precise: 
    has_x = bit_bool() 
    has_y = bit_bool() 
    has_z = bit_bool()
    
    vec = [0.0, 0.0, 0.0]

    IF has_x:
        vec[0] = bit_float32_angle_precise()
    IF has_y:
        vec[1] = bit_float32_angle_precise()
    IF has_z:
        vec[2] = bit_float32_angle_precise()
    
    RETURN vec

bit_qangle_fixed

A 3-component angle vector, where each component is a bit_float32_angle of a fixed bit-size.

FUNCTION bit_qangle_fixed(bits): 
    vec = [0.0, 0.0, 0.0]
    
    vec[0] = bit_float32_angle(bits)
    vec[1] = bit_float32_angle(bits)
    vec[2] = bit_float32_angle(bits)
    
    RETURN vec

bit_qangle_coord

A 3-component angle vector, where each component is a bit_float32_coord. Each component is prefixed with a boolean flag indicating if it's present.

FUNCTION bit_qangle_coord: 
    has_x = bit_bool() 
    has_y = bit_bool() 
    has_z = bit_bool()
    
    vec = [0.0, 0.0, 0.0]

    IF has_x:
        vec[0] = bit_float32_coord()
    IF has_y:
        vec[1] = bit_float32_coord()
    IF has_z:
        vec[2] = bit_float32_coord()
    
    RETURN vec

Vectors

bit_vec3_normal

A 3D normal vector comprised of bit_normal. The X and Y components are read if present, and the Z component is calculated to ensure the vector is of unit length.

FUNCTION bit_vec3_normal(reader):
    value = [0.0, 0.0, 0.0]

    has_x = bit_bool()
    has_y = bit_bool()

    IF has_x:
        value[0] = bit_normal(reader)

    IF has_y:
        value[1] = bit_normal(reader)
    
    is_z_negative = bit_bool()
    
    // Calculate Z to make it a unit vector
    product_sum = value[0] * value[0] + value[1] * value[1]

    IF product_sum < 1.0:
        value[2] = square_root(1.0 - product_sum)
    ELSE:
        value[2] = 0.0
    
    IF is_z_negative:
        value[2] = -value[2]

    RETURN value

bit_vec_float32

FUNCTION bit_vec_float(decoder; degree):
    vec = [0.0] * degree
    FOR i in 0..degree:
        vec[i] = decoder()
    RETURN vec

Game Types

bit_simulation_time

A 32-bit float representing the simulation time of the game, decoded from a bit_varuint_32 and scaled by 1/64.

FUNCTION bit_simulation_time:
    base = bit_varuint_32()
    RETURN base / 64.0

bit_rune_time

A 32-bit float representing the time of the game, decoded as 4 bits

FUNCTION bit_rune_time:
    RETURN read(4)

Writers Note: I am unsure what 'rune' means in this context.

We derived this name from field encoder property "runetime"

bit_ammocount

An unsigned integer 32-bit representing an ammo count, decoded from a bit_varuint_32 with 1 subtracted from it.

FUNCTION bit_ammocount:
    value = bit_varuint_32()
    RETURN MAX(0, value - 1)

Strings

bit_string_n

A UTF-8 string with a fixed length in bytes.

FUNCTION bit_string_n(length):
    bytes = read_bytes(length)
    RETURN string_from_utf8(bytes)

bit_string_null_term

A UTF-8 string that is terminated by a null byte (\0).

FUNCTION bit_string_null_term:
    buffer = []
    LOOP:
        byte = read_byte()
        IF byte == 0:
            BREAK
        buffer.push(byte)
    RETURN string_from_utf8(buffer)

bit_string_terminated

A string that is terminated by a null byte (\0), with a hard-coded limit of 4096 bytes.

FUNCTION bit_string_terminated:
    buffer = ""
    FOR i from 0 to 4096:
        byte = read_byte()
        IF byte == '\0':
            BREAK
        buffer.append(character(byte))
    RETURN buffer