Packet layout
Every packet has the same three-part shape, read in this order:varint-prefixed string
The event name you passed to
Flux.Server or Flux.Client, written with WriteString.
This is what the dispatcher keys listener lookup on, so it is repeated in every packet.
Keep names short if you send at very high frequency.1 byte, or 1 plus a varint
A packed byte holding the packet type and the argument count. See below.
argCount values
Encoded either by the event’s schema or by the dynamic encoder, depending on packet type
and whether a schema is registered.
The header byte
The two-bit packet type sits in the high bits and the argument count in the low six.Bit
7 is the most significant. The type occupies the top two bits because it is written
as packetType << 6, so a header for an event with two arguments is 0x42: 01 in the
high bits, 000010 in the low six.63 is an escape value, not a count. Counts of 0 to 62 fit in the header byte directly;
a count of 63 or more writes 63 in the field and follows it with a varint carrying the
real count. So the header is one byte for essentially all real traffic.Packet types
Only two bits are allocated, so the format has room for one more packet type (
0 is
unused). Values outside 1 to 3 are ignored by both dispatchers rather than raising an
error.EVENT
The payload is the arguments you passed toFire, in order.
schema[i].
Otherwise each is tagged and encoded by WriteAny.
REQUEST
Sent byClient:Invoke. The first payload value is the request id, followed by the invoke
arguments.
The request id is a plain incrementing counter kept per channel name on the client. It is
written with
WriteAny, so a fresh session’s early requests cost one tag plus one byte.RESPONSE
Sent by the server afterOnInvoke returns. The first two payload values are the request
id and a success flag, followed by the handler’s return values.
number
Echoed back from the request so the client can find the parked thread.
boolean
The first result of the server’s
pcall. When false, the next value is the error
message and Invoke re-raises it.The client accepts
true or 1 as success when reading the flag, so the encoding
tolerates the boolean arriving as a narrowed integer.A worked example
Two events fired to the same player in one frame:FireClient carries both packets back to back:
Next steps
Type tags
Every dynamic-encoder tag and its cost.
Buffers API
The read and write primitives behind the format.
