@NAME Protocol Spec, r1

Glossary

Preface

@NAME is a voxel-based video game with a simple, flexible network protocol.

Packet Transport

This spec assumes packets are transported by UDP, on port 21108 by default. Implementations may use other transport protocols, but this internal framing format stays the same, for simplicity.

Packet framing structure
length:  u16 ; This comes first to allow piecewise implementation
counter: u8  ; Increases monotonically, used to detect dropped packets
opcode:  u8
data:    ...

Server/Client IPC Commands

IPC commands start with an uppercase command name, followed by a single ASCII space, and then the command arguments, separated by semicolons if the command takes more than one argument.

(Sv) "KICK"

Sent to the client to notify them that the connection has been closed and the client should stop sending any packets.

Example
KICK Flying cheat detected

(Cl) "CHALLENGE"

Sent by the client to verify they have the private key that goes with their public key. The server sends an encrypted challenge token in the $02 Server Handshake packet. If the client responds with the correct decrypted token, the server can be sure the client is not forging their identity.

Example
CHALLENGE f4c7a28a861d430f

(Bi) "FORMATS"

Sent to mark that a client or server implementation supports a set of file formats or network protocols. Formats that are specified first are given higher priority.

The 'raw' format is 64x64 4-byte ARGB for images, and invalid for other kinds of data.

Example
FORMATS http,https,webp,png,qoi,opus,ogg,dfpwm,wav,raw

(Bi) "RESOURCE"

Sent by the server to give the client additional game resources. Sent from the client to give their skin texture to the server. Resources larger than 60KiB should instead be downloaded over another protocol like HTTP.

Example
RESOURCE skin/ada.tv;data:image/png;...

RESOURCE dm/killstreak.ogg;http://example.com/assets/dm/killstreak.ogg

$00 (Sv): Keep-alive (No payload)

This packet is sent occasionally.

$01 (Bi): Message (2 bytes + variable)

Can contain UTF-8 encoded text or arbitrary binary data.

Packet data structure
channel: u16
message: [u8] ; Remainder of the packet is message data, may be empty

Channels

Channels $0000-$001F are reserved. $0020-$FFFF are for implementation extensions, i.e. plugins, bots, etc.

$02 (Cl): Client Handshake Start (6 bytes + variable)

Sent by the client to initialise a connection to the server. If packet encryption or compression is supported by both ends, they are only used after the handshake process is complete.

The profile key field may be left empty for guest users with ephemeral state.

Packet data structure
version:         u16 ; Currently 0, bumped for incompatible protocol updates
flags:           u16 ; See flag bits section below
name_len:        u8  ; length of UTF-8 nickname in bytes
passkey_len:     u8  ; length of UTF-8 server passkey in bytes (may be zero)
name:            [name_len; u8]
passkey:         [passkey_len; u8]
profile_key:     [u8] ; identity public key, may be empty (TODO)

Flag Bits

$02 (Sv): Server Handshake Start (4 bytes + variable)

Sent by the server in response to a client sending $02 Client Handshake. The server sends an implementation-defined random value encrypted with the client's public key, to verify the client is not forging their identity.

The client responds with "CHALLENGE (...)" with the decrypted data represented as hex on message channel 4. If the client does not respond within 5 seconds or the identity challenge fails, the server sends "KICK challenge_failure" to the client on message channel 4.

Packet data structure
version:       u16
flags:         u16  ; See flag bits section in $02 Client Handshake Start
challenge:     [u8] ; Impl-defined random value, encrypted with client's pubkey