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
encoderproperty"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