Client Synchronization
Client Synchronization
Section titled “Client Synchronization”The client synchronization system replicates server state to connected clients. It uses delta encoding to send only changed data and visibility culling to reduce bandwidth.
Package Location
Section titled “Package Location”- Entity Tracker:
com.hypixel.hytale.server.core.modules.entity.tracker - Chunk Systems:
com.hypixel.hytale.server.core.universe.world.chunk.systems - Protocol:
com.hypixel.hytale.protocol.packets
Architecture Overview
Section titled “Architecture Overview”┌─────────────────────────────────────────────────────────────────┐│ Synchronization Pipeline ││ ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ ││ │ State Change │───►│ Visibility │───►│ Queue Updates │ ││ │ (Component) │ │ Detection │ │ (Delta Encoding) │ ││ └──────────────┘ └──────────────┘ └────────┬─────────┘ ││ │ ││ ┌─────────▼─────────┐ ││ │ SendPackets │ ││ │ (Batch Send) │ ││ └─────────┬─────────┘ ││ │ ││ ┌─────────▼─────────┐ ││ │ Client │ ││ └───────────────────┘ │└─────────────────────────────────────────────────────────────────┘Entity Synchronization
Section titled “Entity Synchronization”NetworkId Component
Section titled “NetworkId Component”Each networked entity has a unique identifier:
package com.hypixel.hytale.server.core.modules.entity.tracker;
public class NetworkId { private int id; // Unique network identifier}Visibility System
Section titled “Visibility System”The system tracks which entities are visible to each player:
| Component | Description |
|---|---|
EntityViewer | Tracks visible entities for a player |
Visible | Tracks which players can see an entity |
System Groups
Section titled “System Groups”Entity synchronization runs in ordered system groups:
| Group | Purpose |
|---|---|
FIND_VISIBLE_ENTITIES_GROUP | Spatial queries for visibility |
QUEUE_UPDATE_GROUP | Queue component changes |
SEND_PACKET_GROUP | Send packets to clients |
Synchronization Flow
Section titled “Synchronization Flow”- State Change: Entity component is modified
- Mark Dirty:
EffectControllerComponentmarks entity as “network outdated” - Visibility Check: Systems determine which players can see the entity
- Queue Update:
QueueComponentUpdatescreates delta update objects - Build Packet: Updates collected into
EntityUpdatespacket - Send: Packet sent to player clients
EntityUpdates Packet
Section titled “EntityUpdates Packet”The main packet for entity state synchronization:
// Packet ID: 161 (compressed)public class EntityUpdates { int[] removed; // Entity IDs to remove EntityUpdate[] updates; // State updates}
public class EntityUpdate { int networkId; // Entity network ID ComponentUpdateType[] removed; // Components to remove ComponentUpdate[] updates; // Component updates}Component Update Types
Section titled “Component Update Types”25 component types can be synchronized:
| Type | Description |
|---|---|
Nameplate | Display names |
UIComponents | Health bars, indicators |
CombatText | Damage numbers |
Model | Entity model |
PlayerSkin | Player skin data |
Item | Held/displayed item |
Block | Block-form entity |
Equipment | Equipment loadout |
EntityStats | Stats and attributes |
Transform | Position, rotation, scale |
MovementStates | Movement flags |
EntityEffects | Active effects/buffs |
Interactions | Interaction options |
DynamicLight | Light emission |
Interactable | Can be interacted with |
Intangible | No collision |
Invulnerable | Cannot be damaged |
RespondToHit | Hit response behavior |
HitboxCollision | Collision settings |
Repulsion | Entity repulsion |
Prediction | Client prediction ID |
Audio | Attached audio |
Mounted | Mount state |
NewSpawn | Newly spawned flag |
ActiveAnimations | Playing animations |
ComponentUpdate Fields
Section titled “ComponentUpdate Fields”Each ComponentUpdate can contain:
public class ComponentUpdate { // Display Nameplate nameplate; EntityUIComponent[] uiComponents; CombatText combatText;
// Visuals Model model; PlayerSkin playerSkin; Item item; Block block; Equipment equipment;
// State EntityStats entityStats; Transform transform; MovementStates movementStates; EntityEffect[] entityEffects;
// Interactions Interaction[] interactions; boolean interactable; boolean intangible; boolean invulnerable;
// Physics HitboxCollision hitboxCollision; Repulsion repulsion; int predictionId;
// Effects DynamicLight dynamicLight; Audio audio; boolean mounted; boolean newSpawn; Animation[] activeAnimations;}Chunk Synchronization
Section titled “Chunk Synchronization”SetChunk Packet
Section titled “SetChunk Packet”Sends complete chunk data to clients:
// Packet ID: 131 (compressed, max 12MB)public class SetChunk { int x, y, z; // Chunk coordinates byte[] localLight; // Local light data byte[] globalLight; // Global light data byte[] data; // Block data}UnloadChunk Packet
Section titled “UnloadChunk Packet”Removes chunk from client:
// Packet ID: 135 (8 bytes)public class UnloadChunk { int chunkX; int chunkZ;}Block Updates
Section titled “Block Updates”Single block changes:
// Packet ID: 140public class ServerSetBlock { int x, y, z; // Block coordinates int blockId; // Block type ID byte filler; // Filler data byte rotation; // Block rotation}Batch block changes:
// Packet ID: 141public class ServerSetBlocks { BlockChange[] changes; // Up to 1024 per packet}Fluid Updates
Section titled “Fluid Updates”// Packet ID: 142public class ServerSetFluid { int x, y, z; int fluidId; byte level;}
// Packet ID: 143public class ServerSetFluids { FluidChange[] changes;}View Radius
Section titled “View Radius”The view radius controls how far clients can see:
// Packet ID: 32public class ViewRadius { int radius; // Chunk distance}Entities and chunks outside the view radius are not synchronized.
Optimization Techniques
Section titled “Optimization Techniques”Delta Encoding
Section titled “Delta Encoding”Only changed components are sent:
- Full update on first visibility
- Incremental updates thereafter
- Remove updates when component is removed
Visibility Culling
Section titled “Visibility Culling”Entities outside view are not synchronized:
- Spatial queries determine visible entities
- Only visible entities queued for updates
- Removed entities send removal packet
Packet Batching
Section titled “Packet Batching”Updates are batched for efficiency:
- Changes queued during tick
- Batch built at end of tick
- Single packet per player per frame
Compression
Section titled “Compression”Large packets use Zstd compression:
SetChunk- Compressed (up to 12MB uncompressed)EntityUpdates- Compressed- Reduces bandwidth significantly
Synchronization Events
Section titled “Synchronization Events”Player Setup
Section titled “Player Setup”When a player joins:
SetClientId- Assign client identifierViewRadius- Set chunk loading distanceSetChunk- Send nearby chunksEntityUpdates- Send visible entities
During Gameplay
Section titled “During Gameplay”Continuous synchronization:
- Entity state changes detected
- Chunk modifications tracked
- Updates batched per tick
- Packets sent to affected players
Entity Spawn/Despawn
Section titled “Entity Spawn/Despawn”New entities:
- Visibility system detects new entity
- Full component update queued
EntityUpdateswithNewSpawnflag sent
Removed entities:
- Entity destroyed or leaves visibility
- Network ID added to
removedarray EntityUpdateswith removal sent
Plugin Considerations
Section titled “Plugin Considerations”Sending Custom Updates
Section titled “Sending Custom Updates”Use existing packet types through PacketHandler:
// Send entity updateEntityUpdates packet = new EntityUpdates();packet.updates = new EntityUpdate[] { update };player.getPacketHandler().write(packet);
// Send block changeServerSetBlock blockPacket = new ServerSetBlock();blockPacket.x = x;blockPacket.y = y;blockPacket.z = z;blockPacket.blockId = blockId;player.getPacketHandler().write(blockPacket);Triggering Sync
Section titled “Triggering Sync”Modify components to trigger automatic sync:
// Component changes automatically queue network updatesTransformComponent transform = entity.getComponent(transformType);transform.setPosition(newPosition);// Entity tracker will detect change and syncBest Practices
Section titled “Best Practices”- Minimize state changes: Frequent changes increase bandwidth
- Use appropriate update types: Don’t send full updates when delta suffices
- Respect view radius: Don’t sync entities outside player view
- Batch operations: Group related changes when possible
- Consider compression: Large data benefits from compression
Related
Section titled “Related”- Networking Overview - Packet system architecture
- Packet Types - All packet IDs
- Entity System - Entity components
- World System - Chunk management