Overview
Voxy World Gen V2 is designed for both singleplayer and multiplayer. In multiplayer mode:- Server generates chunks and ingests them into Voxy
- Clients receive LOD data via custom network packets
- Player tracking manages per-player chunk synchronization
- Dimension handling switches based on player distribution
Server Installation
Install required mods
Place these in your server’s
mods/ folder:- Fabric API (or Quilt Standard Libraries)
- Voxy World Gen V2 (this mod)
- Voxy (for LOD visualization)
Configure Voxy World Gen
Create/edit Server considerations:
config/voxyworldgenv2.json:maxActiveTasks: Start conservative (20-24), increase based on hardwaresaveNormalChunks: true: Important for multiplayer so chunks persist for all players
Client Installation
Every player must install client-side:Install client mods
Place in client
mods/ folder:- Fabric API (or Quilt Standard Libraries)
- Voxy World Gen V2
- Voxy
Join the server
Connect normally. On join, the server sends a handshake packet (see
ServerEventHandler.java:26).Player Tracking
The mod tracks all connected players to determine generation targets.How it works
Code reference:PlayerTracker.java
- Player joins: Added to tracker via
ServerEventHandler.onPlayerJoin(line 24-26) - Player leaves: Removed via
ServerEventHandler.onPlayerDisconnect(line 29-31) - Synced chunks: Each player has a set of chunk positions they’ve received (line 13)
NetworkHandler.java:154-156). This prevents duplicate sends.
Generation follows players
Generation is player-centric. The system:- Gets all online players (line 173 in
ChunkGenerationManager.java) - For each player, finds missing chunks in their radius
- Generates nearest chunks first (via
DistanceGraph)
ChunkGenerationManager.java:183-190
Player movement handling
Every tick, the mod checks player positions:- Chunk changed: Triggers rescan for new missing chunks (line 404)
- Dimension changed: Saves old dimension, loads new dimension state (line 396-397)
- Significant movement: (≥2 chunk distance) Rescans to prioritize new area (line 404)
ChunkGenerationManager.java:377-437 (checkPlayerMovement method)
Dimension Switching
In multiplayer, players may be in different dimensions (Overworld, Nether, End).Dimension priority logic
The mod generates for whichever dimension has the most players. Code reference:ChunkGenerationManager.java:409-423
3 players in Overworld, 1 in Nether
3 players in Overworld, 1 in Nether
Result: Generates OverworldTo switch to Nether, at least 2 players must enter Nether (to have more than Overworld).
2 players in End, 2 in Overworld
2 players in End, 2 in Overworld
Result: Continues current dimension (tie doesn’t trigger switch)One player must switch to break the tie.
All players leave dimension
All players leave dimension
Result: Saves current dimension state, switches to new majority dimensionProgress is saved via
ChunkPersistence.save (line 451 in ChunkGenerationManager.java).Per-dimension state
Each dimension maintains separate state: Code reference:ChunkGenerationManager.java:43-57 (DimensionState class)
- Saved to
world/voxy_gen_minecraft_dimension_*.binfiles - Loaded when dimension becomes active (line 463 in
setupLevel) - Allows resuming generation across server restarts
Chunk Synchronization
Generated chunks are broadcast to nearby clients.Broadcast process
Chunk completes generation
See
ChunkGenerationManager.java:320-330 - after successful generation, calls NetworkHandler.broadcastLODData(chunk)Serialize chunk data
NetworkHandler.java:95-138 serializes:- Block states (per section)
- Biomes (per section)
- Block light (if available)
- Sky light (if available)
Send to nearby players
NetworkHandler.java:143-159 broadcasts to players:- In same dimension
- Within 4096 block radius (64 chunks)
Catch-up synchronization
If a player joins after chunks are generated, they need to catch up. Code reference:ChunkGenerationManager.java:193-228
When no new generation work is available, the worker thread:
- Checks each player’s
syncedChunksset - Finds completed chunks not yet synced to that player
- Sends up to 64 chunks per batch
- Marks them as synced
Network Protocol
The mod uses Fabric Networking API for client-server communication.Packets
1. Handshake (server → client) Code:NetworkHandler.java:27-43
NetworkHandler.java:214-216):
NetworkState.isServerConnected() to true.
2. LOD Data (server → client)
Code: NetworkHandler.java:45-84
- Empty chunk: Not sent (skipped)
- Simple chunk (stone): ~500 bytes
- Complex chunk (structures): 2-5 KB
Registration
Code:NetworkHandler.java:86-93
Server Performance Considerations
CPU allocation
Multiplayer servers share CPU between:- Player tick processing
- Entity updates
- Chunk generation (this mod)
- Network I/O
- Server has 16 cores
- Players use ~6 cores at full load
- Allocate 8-10 cores to generation
maxActiveTasks: 24-32 (roughly 3 tasks per core)
Memory pressure
WithsaveNormalChunks: true, disk offloads memory. But consider:
- Active chunks:
maxActiveTasks × ~50KB= 1-2 MB - Player chunks:
playerCount × viewDistance² × 200KB= dominant factor
- 10 players
- View distance 12 (144 chunks per player)
- 10 × 144 × 200KB ≈ 280 MB just for player chunks
Network bandwidth
Each chunk sent is ~1-3 KB. At 25 c/s generation with 5 players receiving:- 25 chunks/sec × 5 players = 125 packets/sec
- 125 × 2 KB = 250 KB/s outbound
- 100+ Mbps outbound sustained (25+ players actively receiving)
- Generation rate > 100 c/s (requires very high
maxActiveTasks)
maxActiveTasks to slow generation and thus broadcast rate.
Multi-Dimensional Generation Strategy
For servers with players in multiple dimensions:Pre-generation approach
Generate Overworld offline
Before opening to players:
- Start server with no whitelist (or fake player)
- Stand at world spawn
- Wait for generation to complete (remaining: 0)
- Stop server
Generate Nether offline
- Restart server
/execute in minecraft:the_nether run tp @s 0 64 0- Wait for Nether generation
- Stop server
Live generation approach
If players spread across dimensions during gameplay:- Accept switching: Generation follows majority
- Coordinate player distribution: Ask players to stay together initially
- Use multiple phases: “Everyone explore Overworld first, then Nether”
Example Server Configurations
Small community server (5-10 players)
Hardware: 8 cores, 16GB RAM, SSD Config:- Conservative task count leaves headroom for players
- Standard radius provides good LOD coverage
- Saves enabled for persistence across restarts
- 20-30 c/s generation
- ~40-60 KB/s per player bandwidth
- TPS: 19.5-20 (minimal impact)
Large public server (50+ players)
Hardware: 32 cores, 64GB RAM, NVMe RAID Config:- High task count leverages many cores
- Large radius for distant exploration
- Saves enabled (disk is fast NVMe)
- 60-100 c/s generation
- Bandwidth scales with active players in range
- TPS: 19-20 (with proper tuning)
Tellus-enabled modpack server
Hardware: 16 cores, 32GB RAM, SSD Config:- Tellus fast generation supports high concurrency
- Large radius for terrain LODs
- No saves (Tellus regenerates efficiently)
- 80-150 c/s (Tellus is 2-3× faster)
- Lower disk I/O (no saves)
- TPS: 19-20
Monitoring Server Health
Server-side metrics
Check server logs every 5 minutes during initial generation:maxActiveTasks.
Player-side metrics
Ask a trusted player to monitor F3 stats:Automated monitoring
For production servers, log metrics:Troubleshooting Multiplayer Issues
Players not receiving chunks
Symptoms:- Server F3 shows generation
- Client F3 shows “voxy-server: offline”
- Client doesn’t have mod: Install Voxy World Gen V2 on client
- Firewall blocks packets: Check server firewall rules
- Version mismatch: Ensure exact same mod version on client and server
Dimension not generating
Symptoms:- Players in Nether
- F3 shows “remaining: 0”
- No generation happening
High latency/lag
Symptoms:- TPS: 20
- Players report lag
- High network usage
- Reduce
maxActiveTasksto slow generation - Pre-generate world offline
- Temporarily disable mod (
enabled: false) during peak hours
Next Steps
Optimization
Tune server performance settings
Troubleshooting
Debug common multiplayer issues