Networking · const
PROTOCOL_VERSION
The framing, which is small on purpose.
Explained in Networking and rollback.
const PROTOCOL_VERSION = 1import { PROTOCOL_VERSION } from '@driftengine/network';In depth
An input payload is opaque bytes and this file never looks inside one. AGENTS.md: engine
APIs take positions, colours, sizes and time and never another game's noun. A wire format that
knew a player had a throttle would be a racing engine's wire format.
Fixed widths rather than varints
A varint saves two bytes on a tick number and costs a branch per field and a length that cannot be known before encoding. At sixty inputs a second with a payload of a handful of bytes, the saving is under a kilobyte a minute and the cost is that nothing can be written into a preallocated buffer without measuring first. Fixed widths make an input frame a constant size, which is what lets a session own one buffer for the process.
The widths, and what each one refuses
- Participant, one byte. 255 participants in a session, and 255 is not a limit anybody is near: lockstep stops being viable in single figures, and an authoritative host with 255 predicting clients has bandwidth problems long before it has an id problem.
- Tick, four bytes. At 60 Hz an unsigned 32-bit tick counter is 2.2 years of continuous simulation. A session that reaches it has a different problem.
- Payload length, two bytes. 65,535 bytes, which is far more than an input and far less than a full world. A state message that does not fit is a state message that should have been a delta.
The version is in every join, not in every message
A byte per message to say what the protocol was is a byte per message spent on something that cannot change mid-session. The handshake carries it and a mismatch is refused there, which is the one place a peer can still be told why.