Hytale Modding
Hytale Modding

Protocol

This page goes in-depth about the protocol used in our server communication.

Written by Neil Revin

Definitions

The Hytale server accepts connections from UDP clients using the QUIC protocol. The server and clients exchange messages using packets. A packet is a structured unit of data that contains information such as the sender, recipient, and the message payload.

The meaning of a packet depends both on its packet ID and the current state of the connection. The connection can be in one of several states, such as "handshaking", "play", or "status".

Data Types

All data sent over the network is a big-endian byte order. This means that multi-byte values are transmitted with the most significant byte first. For example, the 32-bit integer value 0x12345678 would be sent as the byte sequence 0x12 0x34 0x56 0x78.

NameSize (Bytes)EncodesNotes
Boolean1False or TrueTrue is encoded as 0x01, and False is encoded as 0x00.
Byte1An integer between -128 and 127Signed 8-bit integer, two's complement format.
Unsigned Byte1An integer between 0 and 255Unsigned 8-bit integer.
Short2An integer between -32,768 and 32,767Signed 16-bit integer, two's complement format.
Unsigned Short2An integer between 0 and 65,535Unsigned 16-bit integer.
Int4An integer between -2,147,483,648 and 2,147,483,647Signed 32-bit integer, two's complement format.
Unsigned Int4An integer between 0 and 4,294,967,295Unsigned 32-bit integer.
Long8An integer between -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807Signed 64-bit integer, two's complement format.
Float4A floating-point number32-bit IEEE 754 floating-point format.
Double8A double-precision floating-point number64-bit IEEE 754 floating-point format.
String (n)>= 1 \n < n*3 + 3A sequence of Unicode Scalar valuesUTF-8 String prefixed with its size in bytes as a VarInt. Maxium length of n characters, which varies by context. The encoding used on the wire is regular UTF-8, not Java's "slight modification". However, the length of the string for purposes of length limit is its number of UTF-16 code units, that is, scalar values > U+FFFF are counted as two. Up to nx 3 bytes can be used to encode a UTF-8 string comprising n code units when converted to UTF-16, and both of those limts are checked. Maxium n value is 32767. The +3 is due to the max size of a valid length VarInt

Handshaking

The handshaking process is a multi-phase authentication and validation protocol that establishes secure connections between clients and the server. It supports both token-based and password-based authentication.

Handshake Flow Diagram

rect [rgb(0, 100, 0)] rect [rgb(0, 100, 0)] rect [rgb(200, 0, 0)] alt [Attempts Remaining > 0] [Attempts Exceeded] alt [Hash Matches] [Hash Doesn't Match] alt [Token Valid or No Auth Required] [Authentication Required] Connect (protocol info, client type, optional token) Validate protocol CRC & version AuthGrant (authorization code, server identity token) Store server identity token ServerAuthToken (server token, password challenge) Compute HASH(password, challenge) PasswordResponse (hash) PasswordAccepted PasswordRejected (new challenge, attempts remaining) PasswordResponse (retry with new challenge) PasswordAccepted or PasswordRejected Connection Established ✓ Connection Established ✓ Connection Closed (Lockout) Client Server

Initial Connection

Connect Packet (ID: 0x00)

Direction: Client → Server

Packet IDBound ToField NameField TypeSizeNotes
0x00ServerboundprotocolCRCInt4 bytesCRC integrity check of the protocol definition
0x00ServerboundprotocolBuildNumberInt4 bytesProtocol version number for compatibility checking
0x00ServerboundclientVersionString (20)20 bytes (fixed)Client application version (e.g., "1.0.0")
0x00ServerboundclientTypeByte1 byteClient type: Game (0) or Editor (1)
0x00ServerboundidentityTokenStringvariableAuthentication token from previous session if available
0x00ServerboundlanguageString (16)variable (max 16 chars)Client language preference (RFC 5646 format)
0x00ServerboundreferralDatabyte[]variable (max 4096 bytes)Information about how client was referred
0x00ServerboundreferralSourceHostAddressvariableNetwork address of referral source

Server Authentication Decision

After validating the Connect packet, the server makes one of two decisions:

Direct Access

AuthGrant Packet (ID: 0x0B)

Direction: Server → Client

If the client has a valid existing session token or the server doesn't require authentication, the server grants immediate access.

Packet IDBound ToField NameField TypeSizeNotes
0x0BClientboundauthorizationGrantStringvariable (max 4096 chars)OAuth/authorization code for the client
0x0BClientboundserverIdentityTokenStringvariable (max 8192 chars)Long-lived token identifying this server session. Important: Clients should cache this token for future reconnections

Password Challenge Required

ServerAuthToken Packet (ID: 0x0D)

Direction: Server → Client

If the server doesn't recognize the client or password verification is required:

Packet IDBound ToField NameField TypeSizeNotes
0x0DClientboundserverAccessTokenStringvariable (max 8192 chars)Server-specific access token for this session
0x0DClientboundpasswordChallengebyte[]1-64 bytesCryptographic challenge data (salt/nonce) for password verification

The passwordChallenge is a random nonce that the client must use in conjunction with the user's password to compute a response hash.

ConnectAccept Packet (ID: 0x0E)

Direction: Server → Client

Packet IDBound ToField NameField TypeSizeNotes
0x0EClientboundpasswordChallengebyte[]1-64 bytesCryptographic challenge bytes for the client to respond to

Phase 3: Password Response

PasswordResponse Packet (ID: 0x0F)

Direction: Client → Server

The client responds to the password challenge with a computed hash:

Packet IDBound ToField NameField TypeSizeNotes
0x0FServerboundhashbyte[]1-64 bytesClient-computed hash response: HASH(password + challenge). The hash algorithm and salt strategy is server-defined

Authentication Result

PasswordAccepted Packet (ID: 0x10)

Direction: Server → Client | State: Handshaking

Empty packet signaling successful password authentication.

PasswordRejected Packet (ID: 0x11)

Direction: Server → Client | State: Handshaking

Packet IDBound ToField NameField TypeSizeNotes
0x11ClientboundnewChallengebyte[]1-64 bytesNew challenge for retry attempt
0x11ClientboundattemptsRemainingInt4 bytesNumber of login attempts before lockout. When 0, connection should be terminated

Disconnection

Either the client or server can initiate disconnection at any time:

ClientDisconnect Packet (ID: 0x01)

Direction: Client → Server

Packet IDBound ToField NameField TypeSizeNotes
0x01ServerboundreasonFormattedMessagevariableHuman-readable disconnect reason
0x01ServerboundtypeByte1 byteDisconnect type: Normal (0) or Crash (1)

ServerDisconnect Packet (ID: 0x02)

Direction: Server → Client

Packet IDBound ToField NameField TypeSizeNotes
0x02ClientboundreasonFormattedMessagevariableHuman-readable disconnect reason
0x02ClientboundtypeByte1 byteDisconnect type: Normal (0) or Crash (1)

Handshake State Machine

Connection Initiated Connect received AuthGrant received (valid token) ServerAuthToken received PasswordRejected received(attempts remaining > 0) PasswordAccepted received attemptsRemaining == 0 Ready to join game ClientDisconnect orServerDisconnect received ServerDisconnect received ServerDisconnect received Handshaking AuthGranted AwaitingPassword Disconnected Play