DataSaver
DataSaver is the dedicated SyncNuke synchronization protocol. It’s main goal is to provide reliable synchronization with low communication overhead over connection-oriented communication.
Reference behavior
DataSaverClient implements protocol datasaver, version 0.1.0. It exchanges playback
state and room membership information while filtering updates that match expected progress.
The current client uses QuicClient with BaseCodec.
Session flow
- After the master-server connection,
the client connects to the selected server and sends
JOIN_ROOMwith its username, room, and optional password. - Local playback changes can produce
UPDATE_STATEmessages. Incoming state updates update the client’s expected state and are applied throughPlayerManager. - Incoming
JOIN_ROOMandLEAVE_ROOMmessages update the user list for the current room. - A server
CONNECTmessage redirects the client to another host and port. The client reconnects and sendsJOIN_ROOMagain with the stored session details. - Closing the client sends
LEAVE_ROOMbefore releasing the connection.
State updates
State messages carry play/pause state, position in seconds, and playback speed. They contain no timestamp; the client records its own current time when updating its expected state.
The first local observation and changes between playing and paused trigger an update. For other observations, Core applies these filters in order:
- A position difference within MIN_PROG_CHANGE of the stored expected state is suppressed.
- A larger difference while paused, or with no positive elapsed time, triggers an update.
- While playing, the client compares actual progress with elapsed time multiplied by the observed playback speed. It sends an update when the relative error exceeds DRIFT_THRESHOLD. Expected advances that become zero after integer truncation are suppressed.
A speed-only change can therefore be suppressed by the position filter. The latest expected state is recorded after a successful local send or before applying an incoming update.
The default keep-alive interval is 10 seconds, defined by
DEFAULT_KEEP_ALIVE_INTERVAL_MILLIS.
At each scheduled check, if no message has
been sent for that interval and an expected state is available, the client sends an
UPDATE_STATE with its projected position.
Using a state update as the keep-alive keeps the connection active and regularly refreshes synchronization information. Relying only on change-triggered messages could allow a missed or suppressed update to cause drift that grows over time. Periodic state updates provide an ongoing synchronization reference to help prevent that divergence.
Message format
Messages are consecutive bytes on an ordered stream. The first byte identifies the command; its fields determine the message length. There is no outer length prefix or separator.
All multibyte values use big-endian byte order. u16 is an unsigned 16-bit integer;
f64 is an eight-byte IEEE 754 double. string is a u16 UTF-8 byte count followed by
that many bytes, with a maximum encoded length of 65,535 bytes.
An optional string starts with a one-byte presence marker: 0 means absent; 1 is followed
by a string. An empty, present string has marker 1 and length 0.
Fields follow the command byte in the order shown below.
| Command | Code | Fields | ||
|---|---|---|---|---|
CONNECT | 0x01 | hoststring | portu16 | |
UPDATE_STATE | 0x02 | statebyte | positionf64 | playbackSpeedf64 |
JOIN_ROOM | 0x03 | usernamestring | roomstring | passwordoptional string |
LEAVE_ROOM | 0x04 | usernamestring | roomstring | passwordoptional string |
PING | 0x05 | None | ||
Client behavior
- CONNECT: Receives a server redirect. The client reconnects to the supplied endpoint and rejoins the room; its codec does not encode this command.
- UPDATE_STATE: Sends local and keep-alive state updates, and applies incoming server state.
- JOIN_ROOM: Sends a room join and receives membership notifications.
- LEAVE_ROOM: Sends a departure and receives membership notifications.
- PING: The decoder consumes the command without delivering a message to the client.
Playback state
| State | Code |
|---|---|
PAUSED |
0x00 |
PLAYING |
0x01 |
An UPDATE_STATE message is exactly
18 bytes. For example, paused at position zero with normal speed is:
02 00 00 00 00 00 00 00 00 00 3f f0 00 00 00 00 00 00
Incoming room messages consume the optional password field but discard its value.
The codec rejects unknown command/state codes, invalid optional-string markers, and
truncated messages. Playback value validation is performed by PlayerManager.
The DataSaver CONNECT message carries only host and port. It is separate from the master
protocol’s ConnectData, which also carries the synchronization protocol and version.
Reference material
SyncNuke Core’s DataSaver command model (internal).
DataSaverClient and BaseCodec implement the behavior and message format described above.