This server uses binary WebSocket messages with a small header followed by a payload. The protocol is implemented with .NET BinaryWriter/BinaryReader, so all multi-byte numbers are little-endian.
Important:
.NET BinaryWriter.Write(string)uses a 7-bit encoded integer length prefix (variable length), followed by the string bytes (UTF-8). So string fields do not have a fixed size.
| Type | Size (bytes) | Notes |
|---|---|---|
Int16 |
2 | Used for all action codes and item/scene IDs |
Single / float32 |
4 | Used for coordinates |
GuidString36 |
36 | Fixed-length ASCII string (Guid.ToString("D")), written without a 7-bit length prefix |
string |
L + N |
L = length prefix (7-bit encoded int, 1–5 bytes), N = UTF-8 byte count |
BinaryWriter encodes the string length using a 7-bit encoded integer:
0..127bytes ->L = 1128..16,383bytes ->L = 216,384..2,097,151bytes ->L = 3- etc. (up to 5 bytes)
So the total size of a string field is:
string_size = length_prefix_bytes(L) + utf8_bytes(N)
Note:
GuidString36is not encoded usingBinaryWriter.Write(string). It is sent as raw 36 ASCII bytes with no 7-bit length prefix. SeeAPI.BinaryString36.
All inbound messages begin with:
actionCode: Int16(2 bytes)
Layout
[action:Int16][playerName:string]
Size
2 + (L + N_playerName)
Read order (server)
ReadInt16()-> actionReadString()-> playerName
Layout
[action:Int16]
Size
2
Read order (server)
ReadInt16()-> action
Layout
[action:Int16][x:Single][y:Single][sceneId:Int16]
Size
2 + 4 + 4 + 2 = 12
Read order (server)
ReadInt16()-> actionReadSingle()-> xReadSingle()-> yReadInt16()-> sceneId
Layout
[action:Int16][x:Single][y:Single]
Size
2 + 4 + 4 = 10
Read order (server)
ReadInt16()-> actionReadSingle()-> xReadSingle()-> y
All outbound messages begin with:
actionCode: Int16(2 bytes)
These are built in src/API/BinaryMessageBuilder.cs.
Layout
[action:Int16][playerId:GuidString36][playerName:string]
Size
2 + 36 + (L + N_playerName)
Layout
[action:Int16][playerId:GuidString36]
Size
2 + 36
Layout
[action:Int16][playerId:GuidString36][x:Single][y:Single]
Size
2 + 36 + 4 + 4 = 46
Layout
[action:Int16][playerId:GuidString36][x:Single][y:Single][scene:Int16]
Size
2 + 36 + 4 + 4 + 2 = 48
Layout
[action:Int16][errorMessage:string]
Size
2 + (L + N_errorMessage)
Layout
[action:Int16][successMessage:string]
Size
2 + (L + N_successMessage)
-
Action code width must match.
Both inbound and outbound action codes areInt16(2 bytes). Do not write them asInt32(4 bytes), or all subsequent reads will be offset/wrong. -
playerIdis fixed-length and has NO length prefix.
playerIdis encoded as exactly 36 ASCII bytes (Guid"D"format) and written/read viaAPI.BinaryString36, notBinaryWriter.Write(string)/BinaryReader.ReadString(). -
Other strings are temporarily variable-length.
playerName,successMessage, etc. use the standard.NET BinaryWriterstring encoding (7-bit length prefix + UTF-8). This will be changed in the future.