Overview
TheDistanceGraph is a hierarchical spatial data structure that tracks chunk generation state across infinite worlds and efficiently finds the nearest ungenerated chunks to any player. It solves the fundamental challenge:
Given millions of potentially-required chunks, how do we find the next 16 to generate in O(log n) time?
Architecture
The system uses a 4-level hierarchy where each level groups chunks into progressively larger regions:Node Structure
fullMask: Each bit represents one of 64 child nodes/batches (8×8 grid)children: Only stores partially complete children (memory optimization)- Level 1 children:
Integerbitmask (16 bits for 4×4 chunks) - Level 2+ children:
Nodereferences
Memory Optimization
The graph uses sparse storage:- Fully generated regions: Only a bit in parent’s
fullMask(1 bit) - Empty regions: No storage at all (0 bytes)
- Partially generated: Full
Nodeobject
Core Operations
markChunkCompleted
Purpose: Mark a single chunk as generated and propagate completion up the hierarchy- Convert chunk coordinates
(cx, cz)to batch coordinates(bx, bz) - Calculate which bit within the batch (0-15)
- Find or create the root node for this region
- Recursively traverse down, marking nodes complete
findWork
Purpose: Find the nearest ungenerated 4×4 batch to a playercenter: Player’s chunk positionradiusChunks: Maximum search radius (from configgenerationRadius)trackedBatches: Set of batch keys already queued (prevents duplicates)
- Early pruning: Skip entire regions outside search radius
- Sparse traversal: Only visit nodes that exist or have ungenerated children
- Distance sorting: Always process closest nodes first
- Empty space handling: Treat null nodes as incomplete (allows finding work in unexplored areas)
Distance Calculation
Purpose: Calculate squared distance from a point to the nearest edge of a rectangular node- Avoids expensive
sqrt()calls - Comparison order is preserved: if
a² < b²thena < b - Used for priority queue sorting and radius checks
dx = dz = 0, giving distance 0.
countMissingInRange
Purpose: Estimate how many chunks still need generation within a radiusChunkGenerationManager.restartScan() to update the “Remaining” counter in the debug overlay
Algorithm: Recursive traversal with estimation
collectCompletedInRange
Purpose: Gather completed chunks near a player for LOD synchronization- Near-to-far ordering: Priority queue ensures closest chunks sync first
- Deduplication: Skips chunks in
alreadySyncedset - Batch limiting: Stops after
maxResults(typically 64) - Virtual full nodes: Propagates full state without needing the actual node reference
Batch Tracking System
TheDistanceGraph works in tandem with ChunkGenerationManager to track in-flight batches:
Batch Keys
trackedBatches to prevent findWork() from returning the same batch twice.
Batch Lifecycle
- Amortizes overhead: 16 chunks share one
findWork()call - Spatial locality: Nearby chunks often load faster due to caching
- Progress tracking: Easier to estimate completion
Thread Safety
Synchronization Strategy
- Node.fullMask: Marked
volatile- reads/writes are atomic - Node.children:
ConcurrentHashMap- thread-safe - roots:
ConcurrentHashMap- thread-safe - Critical sections:
synchronized(node)when updating bothfullMaskandchildren
- See the old
fullMask - Try to access
children.get(idx) - Get
nullbecause it was already removed - Crash with
NullPointerException
Performance Characteristics
| Operation | Time Complexity | Space Complexity |
|---|---|---|
markChunkCompleted | O(1) - 4 levels | O(log n) nodes |
findWork | O(r²) worst, O(r log r) typical | O(r²) queue items |
countMissingInRange | O(visible nodes) | O(1) stack depth |
collectCompletedInRange | O(k log k) where k=results | O(r²) queue items |
- Empty world: ~0 KB
- 50% complete world: ~500 KB per 100M chunk area
- 99% complete world: ~50 KB per 100M chunk area
Visualization Example
Player at chunk(100, 100), radius 32 chunks:
findWork() traverses: Root → Node → Batch → Return 4 missing chunks
Common Patterns
Prioritizing Multiple Players
Checking Progress
Syncing New Players
Related Documentation
- Events - How the manager coordinates with the distance graph
- Mixins - Low-level hooks that feed completion data
- Configuration -
generationRadiusaffects search space - Performance - Tuning batch size and throttling