Types

Primitive types

TypeSizeDescription
bool1 bitTrue or false
u8 -- u648--64 bitsUnsigned integers
i8 -- i648--64 bitsSigned integers (two's complement)
f3232 bitsIEEE 754 single-precision float
f6464 bitsIEEE 754 double-precision float
fixed3232 bitsQ16.16 fixed-point (two's complement)
fixed6464 bitsQ32.32 fixed-point (two's complement)

Fixed-point types (fixed32, fixed64) give the protocol an explicit scaled integer representation. That avoids platform-dependent wire representation for fractional values. Applications still choose their arithmetic, overflow, and rounding policy.

The @varint annotation is valid on fixed32 and fixed64, encoding the raw i32/i64 as unsigned LEB128 for variable-length wire representation.

Sub-byte types

TypeSizeDescription
u1 -- u71--7 bitsUnsigned sub-byte integers
i2 -- i72--7 bitsSigned sub-byte integers

Sub-byte fields are packed LSB-first within each byte. Use them when the wire contract needs widths smaller than a byte, rather than modelling a packed value through application-side masks.

Semantic types

TypeWire encodingDescription
stringLEB128 length + UTF-8Text
bytesLEB128 length + rawBinary data
uuid16 bytesUUID as raw bytes
timestamp64-bit signedUnix epoch (interpretation is application-defined)
rgb3 bytesRed, green, blue
hash32 bytesBLAKE3 hash

Parameterized types

TypeDescription
optional<T>Presence bit + value
array<T>LEB128 count + elements
array<T, N>Fixed-size array (no count prefix, N elements)
map<K, V>LEB128 count + sorted key-value pairs
result<T, E>Boolean tag + ok or error value
set<T>LEB128 count + sorted unique elements

Fixed-size arrays (array<T, N>) have no length prefix on the wire -- the size is part of the schema. N must be a compile-time constant.

Sets (set<T>) are unordered unique collections. Elements are sorted on encode for deterministic wire representation. Duplicates are silently deduplicated.

Geometric types

Graphics and simulation primitives with deterministic wire encoding:

TypeComponentsDescription
vec2<T>x, y2D vector
vec3<T>x, y, z3D vector
vec4<T>x, y, z, w4D vector or homogeneous coordinate
quat<T>x, y, z, wQuaternion rotation
mat3<T>9 components3x3 matrix (column-major)
mat4<T>16 components4x4 matrix (column-major)

Valid element types: fixed32, fixed64, f32, f64.

Examples:

message Transform {
    position @0 : vec3<fixed64>   # deterministic simulation position
    rotation @1 : quat<fixed64>   # deterministic quaternion
    gl_pos   @2 : vec3<f32>       # GPU-ready render position
    model    @3 : mat4<f32>       # 4x4 transform matrix
}

Wire encoding: components written in order (x, y, z, w), no padding, no count prefix. Total size = N components x element size.

Inline bitfields

Anonymous flags for compact permission or storage bits:

message FileHeader {
    perms @0 : bits { r, w, x, hidden, system }
}

Wire encoding: exactly N bits (one per named flag), LSB-first. The example above uses 5 bits.

Wire encoding

All types encode to a deterministic byte sequence. Fixed-size types pack at their natural bit width. Variable-length types (string, bytes, array, map, set) use LEB128 length prefixes.

The @varint annotation changes a fixed-width integer to unsigned LEB128 encoding. The @zigzag annotation uses ZigZag encoding for signed integers (small magnitudes use fewer bytes). The @delta annotation generates stateful encoder/decoder pairs that transmit field-level deltas.

See the language specification for complete encoding rules.