Skip to content

five-on-it / packages/protocol/src/codec

packages/protocol/src/codec ​

Binary layouts (little-endian). The first byte is the message kind.

input    u8 kind=1 | u32 seq | record
inputs   u8 kind=7 | u32 ack | u32 newestSeq | u8 count | record*  (newest first)
record   i8 throttle*127 | i8 steer*127 | u8 flags | u16 aim
         | u8 target | u8 flags2 | u8 aimDistance*4 | u8 slot | i8 transfer | u8 service
snapshot u8 kind=3 | u32 tick | u32 lastSeq | u8 inputBuffer | u16 count | entity* | u8 events | event*
entity   u16 eid | u16 owner | f32 x y z | f32 qx qy qz qw | f32 vx vy vz | f32 wx wy wz
         | i8 steer*127 | u8 flags | u8 cls | u8 kind | u16 inside | u8 seat
         | u8 boost*255 | u8 landing*100 | u8 gripFront*255 | u8 gripRear*255
         | u8 wheelContact | u8 tyres | u16 aim | u8 weapon | u8 health | u8 cover
         | u16 coverYaw | u8 cooking | u8 flags2 | u8 status | u8 alert | u8 ownerKind
         | u16 ownerId | u8 paint | u8 act | u8 flags3 | u8 gen
event    u8 kind | u16 owner | u8 weapon | f32 x y z | u16 yaw | f32 length | u16 pitch | u16 target

Flag bit i is the i-th name of its *_FLAGS table below; an input's phone (0 to 3) rides in the top bit of flags (its low bit) and of flags2 (its high bit). A kind is its index in its *_KINDS table; an entity's act is the simulation's act byte (what a character does with its hands and the counter of its acts). Angles (the aim, the direction into the cover, a shot's yaw and pitch) are 16-bit turns. inside and an event's target are 0xFFFF for "none". An entity's gen is its life under its id (the simulation turns it over when the id is freed), so one life's record is never read as another's.

Inputs are quantized to the wire precision before being applied locally, so the predicting client and the server simulate exactly the same numbers. A client sends its last few inputs in every frame (inputs, kind 7: one over a WebSocket, four over a transport that loses frames, an input lost in one frame coming in the next), each one's number implied (newestSeq - i), with the newest snapshot tick it applied as ack; a client that sends no inputs (a frozen room) sends the ack alone now and then. The single input (kind 1) is still read, for older bots and the load harness.

Variables ​

Functions ​