Hytale Server API - Networking & Packet System

Packet Interface

Location: com/hypixel/hytale/protocol/Packet.java

public interface Packet {
    int getId();
    void serialize(@Nonnull ByteBuf byteBuf);
    int computeSize();
}

Frame Format

[4 bytes: LE payload length]
[4 bytes: LE packet ID]
[N bytes: payload (compressed or uncompressed)]

Constants:

  • Frame header: 8 bytes minimum
  • Maximum payload size: 1,677,721,600 bytes (1.6 GB)
  • All integers: Little-Endian byte order

PacketRegistry

Location: com/hypixel/hytale/protocol/PacketRegistry.java

PacketInfo Structure

public static final class PacketInfo extends Record {
    int id;
    String name;
    Class<? extends Packet> type;
    int fixedBlockSize;
    int maxSize;
    boolean compressed;
    BiFunction<ByteBuf, Integer, ValidationResult> validate;
    BiFunction<ByteBuf, Integer, Packet> deserialize;
}

Key Methods

MethodDescription
getById(int id)Lookup packet by ID
getId(Class)Lookup ID by packet type
all()Get all registered packets

Packet Categories

Connection Control (0-3)

IDPacketCompressedFixed SizeMax Size
0ConnectNo8238,161
1DisconnectNo216,384,007
2PingNo2929
3PongNo2020

Authentication (10-18)

IDPacketCompressedDescription
10StatusNoServer status
11AuthGrantNoAuth grant (max 49,171)
12AuthTokenNoClient auth token
13ServerAuthTokenNoServer auth token
14ConnectAcceptNoConnection accepted
15PasswordResponseNoPassword response
16PasswordAcceptedNoPassword valid
17PasswordRejectedNoPassword invalid
18ClientReferralNoReferral data

World Setup (20-34)

IDPacketCompressedDescription
20WorldSettingsYesWorld configuration
21WorldLoadProgressNoLoading progress
22WorldLoadFinishedNoLoading complete
23RequestAssetsYesAsset request
24InitializeAssetsYesAsset init
25AssetPartYesAsset chunk
26FinalizeAssetsYesAsset complete
27-28Asset management--
29-34Update rate, time, features--

Asset Updates (40-85)

IDPacketDescription
40UpdateBlockTypesBlock type definitions
41UpdateBlockHitboxesBlock collision data
42UpdateBlockSoundSetsBlock sounds
43UpdateItemSoundSetsItem sounds
44UpdateBlockParticleSetsBlock particles
45-85Various asset updatesAll compressed

Player & Movement (100-130)

IDPacketCompressedFixed SizeDescription
100SetClientIdNo4Assign client ID
101SetGameModeNo-Game mode change
102SetMovementStatesNo-Movement state flags
103SetBlockPlacementOverrideNo-Placement override
104JoinWorldNo18World entry
105ClientReadyNo-Client ready signal
106LoadHotbarNo-Load hotbar
107SaveHotbarNo-Save hotbar
108ClientMovementNo153Position/velocity
109ClientTeleportNo52Teleport
110UpdateMovementSettingsNo252Movement config
111MouseInteractionNo-Mouse input

World/Chunk Management (131-159)

IDPacketCompressedFixed SizeDescription
131SetChunkYes13Chunk data
132SetChunkHeightmapYes-Heightmap data
133SetChunkTintmapYes-Tint data
134SetChunkEnvironmentsYes-Environment data
135UnloadChunkNo8Unload chunk
136SetFluidsYes13Fluid data
137ServerSetBlockNo19Single block
141ServerSetBlocksNo-Multiple blocks
142ServerSetFluidNo-Single fluid
143ServerSetFluidsNo-Multiple fluids

Time & Weather (145-152)

IDPacketCompressedFixed Size
145UpdateTimeSettingsNo10
146UpdateTimeNo13
147UpdateEditorTimeOverrideNo14
148ClearEditorTimeOverrideNo-
149UpdateWeatherNo8
150UpdateEditorWeatherOverrideNo-

Entity Updates (160-168)

IDPacketCompressedFixed SizeDescription
160SetEntitySeedNo4Entity seed
161EntityUpdatesYes-Batch entity updates
162PlayAnimationNo-Animation playback
163ChangeVelocityNo35Velocity change
164ApplyKnockbackNo38Knockback effect
165SpawnModelParticlesNo-Model particles
166MountMovementNo59Mount movement
167MountNPCNo16Mount entity
168DismountNPCNo0Dismount entity

Inventory (167-179)

IDPacketCompressedFixed SizeDescription
167UpdatePlayerInventoryYes-Inventory update
171SetCreativeItemNo-Creative mode item
172DropCreativeItemNo-Drop creative item
173SmartGiveCreativeItemNo-Smart give item
174DropItemStackNo12Drop item
175MoveItemStackNo20Move item
176SmartMoveItemStackNo13Smart move item
177SetActiveSlotNo8Active slot
178SwitchHotbarBlockSetNo-Hotbar set
179InventoryActionNo6Inventory action

Windows/UI (200-221)

IDPacketCompressedFixed SizeDescription
200OpenWindowYes-Open window
201UpdateWindowYes-Update window
202CloseWindowNo4Close window
203SendWindowActionNo-Window action
204ClientOpenWindowNo-Client open
210ServerMessageNo-Server message
211ChatMessageNo-Chat message
212NotificationNo-Notification
213KillFeedMessageNo-Kill feed
214ShowEventTitleNo-Event title
215HideEventTitleNo4Hide title
216SetPageNo2Set page
217CustomHudYes-Custom HUD
218CustomPageYes-Custom page
219CustomPageEventNo-Page event
220EditorBlocksChangeYes-Editor blocks
221ServerInfoNo-Server info

Camera (258-261)

IDPacketCompressedFixed Size
258SetServerCameraNo157
259CameraShakeEffectNo9
260RequestFlyCameraModeNo1
261SetFlyCameraModeNo1

Interactions (264-268)

IDPacketCompressedFixed SizeDescription
264SyncInteractionChainsNo-Sync chains
265CancelInteractionChainNo-Cancel chain
266PlayInteractionForNo-Play interaction
267MountNPCNo16Mount NPC
268DismountNPCNo0Dismount

Asset Editor (300+)

IDPacketCompressedDescription
300FailureReplyNoOperation failed
301SuccessReplyNoOperation success
302+Editor packetsYesAsset editor

Netty Pipeline

PacketEncoder

Location: com/hypixel/hytale/protocol/io/netty/PacketEncoder.java

@ChannelHandler.Sharable
public class PacketEncoder extends MessageToByteEncoder<Packet>

Handles:

  • CachedPacket detection and reuse
  • PacketStatsRecorder lookup
  • Frame writing via PacketIO

PacketDecoder

Location: com/hypixel/hytale/protocol/io/netty/PacketDecoder.java

public class PacketDecoder extends ByteToMessageDecoder

Constants:

  • LENGTH_PREFIX_SIZE = 4
  • PACKET_ID_SIZE = 4
  • MIN_FRAME_SIZE = 8

Process:

  1. Wait for minimum 8 bytes
  2. Read 4-byte LE payload length
  3. Validate length <= 1,677,721,600
  4. Read 4-byte LE packet ID
  5. Lookup PacketInfo
  6. Wait for complete frame
  7. Decompress if needed
  8. Deserialize packet

Compression (ZStd)

  • Library: com.github.luben.zstd
  • Level: -Dhytale.protocol.compressionLevel (default: Zstd.defaultCompressionLevel())
  • Applied to packets marked compressed=true in PacketRegistry

Serialization Helpers

VarInt Encoding

Location: com/hypixel/hytale/protocol/io/VarInt.java

7 bits per byte with continuation bit:

RangeBytes
0 - 1271
128 - 16,3832
16,384 - 2,097,1513
2,097,152 - 268,435,4554
268,435,456+5

Methods:

void write(ByteBuf buf, int value)
int read(ByteBuf buf)
int peek(ByteBuf buf, int index)
int length(ByteBuf buf, int index)
int size(int value)

String Encoding

Fixed-length (null-padded):

readFixedString(ByteBuf, int offset, int length)
readFixedAsciiString(ByteBuf, int offset, int length)
writeFixedString(ByteBuf, String, int length)
writeFixedAsciiString(ByteBuf, String, int length)

Variable-length (VarInt-prefixed):

readVarString(ByteBuf, int offset)
readVarAsciiString(ByteBuf, int offset)
writeVarString(ByteBuf, String, int maxLength)
writeVarAsciiString(ByteBuf, String, int maxLength)

Other Types

// Byte arrays
readBytes(ByteBuf, int offset, int length)
readByteArray(ByteBuf, int offset, int length)
writeFixedBytes(ByteBuf, byte[], int length)

// Numeric arrays
readShortArrayLE(ByteBuf, int offset, int length)
readFloatArrayLE(ByteBuf, int offset, int length)

// IEEE 16-bit float
readHalfLE(ByteBuf, int index)
writeHalfLE(ByteBuf, float value)

// UUID (16 bytes)
readUUID(ByteBuf, int offset)
writeUUID(ByteBuf, UUID)

PacketHandler

Location: com/hypixel/hytale/server/core/io/PacketHandler.java

public abstract class PacketHandler implements IPacketReceiver {
    public static final int MAX_PACKET_ID = 512;
}

Abstract Methods:

String getIdentifier();
void accept(Packet packet);

Packet Sending:

void write(Packet... packets)
void write(Packet packet)
void writeNoCache(Packet packet)
void writePacket(Packet packet, boolean cache)

Queuing:

void setQueuePackets(boolean queuePackets)
void tryFlush()

Connection:

void disconnect(String message)
void registered(PacketHandler oldHandler)
void unregistered(PacketHandler newHandler)
void closed(ChannelHandlerContext ctx)

Ping:

void tickPing(float dt)
void sendPing()
void handlePong(Pong packet)
PingInfo getPingInfo(PongType pongType)

PingInfo

public static class PingInfo {
    public static final TimeUnit TIME_UNIT = TimeUnit.MICROSECONDS;
    public static final TimeUnit PING_FREQUENCY_UNIT = TimeUnit.SECONDS;
    public static final int PING_HISTORY_LENGTH = 15;
}

CachedPacket

Location: com/hypixel/hytale/protocol/CachedPacket.java

Wraps packets to cache serialized ByteBuf:

CachedPacket<T> cache(T packet)
Class<T> getPacketType()
int getCachedSize()

Packet Statistics

Location: com/hypixel/hytale/protocol/io/PacketStatsRecorder.java

public interface PacketStatsRecorder {
    AttributeKey<PacketStatsRecorder> CHANNEL_KEY;
    PacketStatsRecorder NOOP;

    void recordSend(int packetId, int uncompressedSize, int compressedSize);
    void recordReceive(int packetId, int uncompressedSize, int compressedSize);
    PacketStatsEntry getEntry(int packetId);
}

Tracks:

  • Send/receive counts
  • Uncompressed/compressed sizes (min, max, avg, total)
  • Recent statistics (last 30 seconds)

Protocol Utilities

Location: com/hypixel/hytale/protocol/io/netty/ProtocolUtil.java

Application Error Codes:

CodeConstant
0APPLICATION_NO_ERROR
1APPLICATION_RATE_LIMITED
2APPLICATION_AUTH_FAILED
3APPLICATION_INVALID_VERSION

Methods:

void closeConnection(Channel channel)
void closeConnection(Channel channel, QuicTransportError error)
void closeApplicationConnection(Channel channel)
void closeApplicationConnection(Channel channel, int errorCode)

Supports both QuicChannel and QuicStreamChannel.


Connect Packet Example

ID: 0 Compressed: No Fixed Size: 82 bytes

Fields:

FieldTypeSizeDescription
protocolHashString64 bytesFixed ASCII
clientTypeClientType1 byteEnum
uuidUUID16 bytesPlayer UUID
languageStringVariableOptional ASCII
identityTokenStringVariableOptional UTF-8
usernameStringVariableASCII (max 16)
referralDatabyte[]VariableOptional
referralSourceHostAddressVariableOptional

Layout:

[0-1]     Nullable bit field
[1-65]    protocolHash (64 bytes)
[65]      clientType (1 byte)
[66-81]   uuid (16 bytes)
[82-85]   language offset
[86-89]   identityToken offset
[90-93]   username offset
[94-97]   referralData offset
[98-101]  referralSource offset
[102+]    Variable field data