Overview
TheNetworkHandler class manages client-server communication for LOD (Level of Detail) chunk data. It defines custom network payloads for handshake negotiation and chunk data transmission, using Fabric’s networking API.
Package: com.ethan.voxyworldgenv2.network
Network Protocol
The mod uses two custom packet types:Bidirectional handshake to confirm both client and server have the mod installed
Server-to-client packet containing serialized chunk section data with lighting and biomes
Packet Identifiers
Payloads
HandshakePayload
Confirms mod presence on client or server.true if the server has the mod installed, false otherwise- Size: 1 byte
- Content: Boolean flag
LODDataPayload
Transmits chunk section data including block states, biomes, and lighting.The chunk position (X, Z coordinates)
Minimum section Y coordinate (e.g., -4 for worlds starting at Y=-64)
List of non-empty chunk sections with serialized data
SectionData
Contains serialized data for a single 16×16×16 chunk section.Section Y coordinate (vertical index)
Serialized
PalettedContainer<BlockState> dataSerialized
PalettedContainer<Biome> data2048 bytes (4096 nibbles) of block light data, or
null if not available2048 bytes (4096 nibbles) of sky light data, or
null if not available- Block states and biomes use Minecraft’s
PalettedContainerformat - Data is registry-aware (uses
RegistryFriendlyByteBuf) - Light data uses
DataLayerformat (2048 bytes per section) - Null light arrays are explicitly supported (sent as nullable fields)
Methods
init
Initializes the network handler by registering packet types with Fabric.- Registers
HandshakePayloadfor both C2S (client-to-server) and S2C (server-to-client) - Registers
LODDataPayloadfor S2C only - Must be called during mod initialization (typically in
onInitialize()) - Logs “voxy networking initialized” on success
broadcastLODData
Broadcasts LOD chunk data to all nearby players.The chunk to serialize and broadcast
- Serialization: Converts non-empty sections to
SectionDatarecords- Serializes block states using
PalettedContainer.write() - Serializes biomes using
PalettedContainer.write() - Extracts block and sky light from the light engine
- Serializes block states using
- Player Selection: Sends to all players within 4096 blocks (squared distance)
- Tracking: Marks chunks as synced for each player in
PlayerTracker - Early Exit: Returns immediately if all sections are air
- Uses Netty’s
Unpooled.buffer()for serialization - Properly releases buffers in
finallyblocks to prevent memory leaks - Clones light data arrays to avoid concurrent modification
- Skips empty sections to reduce packet size
sendLODData
Sends LOD chunk data to a specific player.The player to send data to
The chunk to serialize and send
- Identical serialization process to
broadcastLODData - Sends only to the specified player (no range check)
- Marks chunk as synced in
PlayerTrackerfor the player - Returns immediately if all sections are air
- Player login/respawn (send nearby chunks)
- Manual synchronization after terrain modification
- Targeted updates for specific players
sendHandshake
Sends a handshake packet to a player to confirm server-side mod presence.The player to send the handshake to
- Sends
HandshakePayload(true)to the player - Typically called immediately after player login
- Client can respond with their own handshake to confirm bidirectional support
HandshakePayload to detect server-side mod presence and respond with its own handshake if needed.
Implementation Details
Serialization Process
BothbroadcastLODData and sendLODData follow the same serialization pipeline:
- Section Filtering: Skip null or air-only sections (
section.hasOnlyAir()) - Buffer Creation: Allocate Netty
ByteBufinstances for states and biomes - State Serialization:
- Biome Serialization: Same process using
section.getBiomes() - Light Extraction:
- Data Cloning: Light arrays are cloned to prevent concurrent modification
- Buffer Cleanup:
finallyblocks ensure buffers are released
Memory Management
Proper resource cleanup is critical:- Netty buffers are released in
finallyblocks - Light data is cloned (not referenced directly)
- Empty sections are skipped to reduce memory usage
- No lingering references to chunk data after method returns
Packet Size
Typical packet sizes:- Handshake: 1 byte
- LOD Data: Varies by chunk complexity
- Empty chunk: 0 bytes (not sent)
- Typical chunk: 10-50 KB
- Complex chunk: Up to 200 KB
- Number of non-empty sections
- Block state palette size
- Biome palette size
- Presence of lighting data
Thread Safety
All methods are safe to call from the server thread:- Serialization occurs on the calling thread
- Fabric networking handles packet queuing
- No shared mutable state in
NetworkHandler
PlayerTracker Integration
The handler integrates withPlayerTracker to track synchronized chunks:
Client-Side Implementation
The server-side API shown here must be paired with client-side handlers:The client-side implementation is not shown here. Refer to the client-side code for details on handling received packets.
Error Handling
- Serialization Failures: Netty buffers are always released, preventing memory leaks
- Missing Light Data: Sent as
nullin payload (handled by nullable fields) - Player Disconnection: Fabric networking handles gracefully (packets are dropped)
- Invalid Registry Access: Would throw during serialization (bug in calling code)
Source Reference
SeeNetworkHandler.java:23-217 for the complete implementation.