242 lines
5.4 KiB
Markdown
242 lines
5.4 KiB
Markdown
---
|
|
title: World Loader
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
The World Loader system manages chunk loading, generation scheduling, and world streaming.
|
|
|
|
**Package:** `com.hypixel.hytale.server.worldgen.loader`
|
|
|
|
## WorldLoader Class
|
|
|
|
The `WorldLoader` coordinates chunk loading and generation:
|
|
|
|
```java
|
|
public class WorldLoader {
|
|
// Load chunk at coordinates
|
|
public CompletableFuture<Chunk> loadChunk(int chunkX, int chunkZ);
|
|
|
|
// Unload chunk
|
|
public void unloadChunk(int chunkX, int chunkZ);
|
|
|
|
// Check if chunk is loaded
|
|
public boolean isChunkLoaded(int chunkX, int chunkZ);
|
|
|
|
// Get loaded chunk
|
|
public Chunk getChunk(int chunkX, int chunkZ);
|
|
|
|
// Request chunk generation
|
|
public void requestGeneration(int chunkX, int chunkZ, int priority);
|
|
}
|
|
```
|
|
|
|
## Loading Pipeline
|
|
|
|
The chunk loading process follows several stages:
|
|
|
|
```
|
|
Chunk Loading Pipeline
|
|
├── 1. Check Cache
|
|
│ └── Return if cached
|
|
├── 2. Load from Disk
|
|
│ └── Return if saved
|
|
├── 3. Queue for Generation
|
|
│ ├── Priority Assignment
|
|
│ └── Thread Pool Dispatch
|
|
├── 4. Generate Chunk
|
|
│ ├── Terrain Pass
|
|
│ ├── Cave Pass
|
|
│ ├── Structure Pass
|
|
│ └── Decoration Pass
|
|
└── 5. Cache and Return
|
|
```
|
|
|
|
## ChunkLoadRequest
|
|
|
|
```java
|
|
public class ChunkLoadRequest {
|
|
private int chunkX;
|
|
private int chunkZ;
|
|
private int priority;
|
|
private LoadReason reason;
|
|
private CompletableFuture<Chunk> future;
|
|
|
|
public enum LoadReason {
|
|
PLAYER_PROXIMITY,
|
|
ENTITY_SPAWN,
|
|
STRUCTURE_CHECK,
|
|
EXPLICIT_REQUEST
|
|
}
|
|
}
|
|
```
|
|
|
|
## Load Priority System
|
|
|
|
Chunks are loaded based on priority:
|
|
|
|
```java
|
|
public class LoadPriority {
|
|
// Highest priority - player's current chunk
|
|
public static final int IMMEDIATE = 0;
|
|
|
|
// High priority - chunks around player
|
|
public static final int PLAYER_VIEW = 100;
|
|
|
|
// Normal priority - entity needs
|
|
public static final int ENTITY = 200;
|
|
|
|
// Low priority - preloading
|
|
public static final int PRELOAD = 300;
|
|
|
|
// Lowest priority - background tasks
|
|
public static final int BACKGROUND = 400;
|
|
}
|
|
```
|
|
|
|
## Generation Threading
|
|
|
|
World generation uses a thread pool:
|
|
|
|
```java
|
|
public class GenerationThreadPool {
|
|
private int threadCount;
|
|
private PriorityBlockingQueue<ChunkLoadRequest> queue;
|
|
|
|
// Configure thread count
|
|
public void setThreadCount(int count);
|
|
|
|
// Get queue size
|
|
public int getPendingCount();
|
|
|
|
// Clear low-priority requests
|
|
public void clearLowPriority(int threshold);
|
|
}
|
|
```
|
|
|
|
## Chunk Cache
|
|
|
|
The loader maintains a chunk cache:
|
|
|
|
```java
|
|
public class ChunkCache {
|
|
private int maxSize;
|
|
private Map<ChunkPos, Chunk> cache;
|
|
|
|
// Get cached chunk
|
|
public Chunk get(int chunkX, int chunkZ);
|
|
|
|
// Add to cache
|
|
public void put(int chunkX, int chunkZ, Chunk chunk);
|
|
|
|
// Remove from cache
|
|
public void invalidate(int chunkX, int chunkZ);
|
|
|
|
// Clear cache
|
|
public void clear();
|
|
|
|
// Get cache statistics
|
|
public CacheStats getStats();
|
|
}
|
|
```
|
|
|
|
## View Distance Loading
|
|
|
|
```java
|
|
public class ViewDistanceLoader {
|
|
private int viewDistance;
|
|
private Player player;
|
|
|
|
// Update loaded chunks for player
|
|
public void updatePlayerChunks(Player player) {
|
|
Vector3d pos = player.getPosition();
|
|
int centerX = (int) pos.x >> 4;
|
|
int centerZ = (int) pos.z >> 4;
|
|
|
|
// Load chunks in view distance
|
|
for (int dx = -viewDistance; dx <= viewDistance; dx++) {
|
|
for (int dz = -viewDistance; dz <= viewDistance; dz++) {
|
|
int priority = Math.abs(dx) + Math.abs(dz);
|
|
worldLoader.requestGeneration(centerX + dx, centerZ + dz, priority);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Container System
|
|
|
|
Generation containers manage intermediate data:
|
|
|
|
```java
|
|
public class GenerationContainer {
|
|
private int chunkX;
|
|
private int chunkZ;
|
|
private BlockBuffer blockBuffer;
|
|
private BiomeMap biomeMap;
|
|
private HeightMap heightMap;
|
|
|
|
// Set block in container
|
|
public void setBlock(int x, int y, int z, BlockType type);
|
|
|
|
// Get block from container
|
|
public BlockType getBlock(int x, int y, int z);
|
|
|
|
// Finalize to chunk
|
|
public Chunk toChunk();
|
|
}
|
|
```
|
|
|
|
## Event Hooks
|
|
|
|
```java
|
|
// Pre-generation event
|
|
getEventRegistry().register(ChunkPreGenerateEvent.class, event -> {
|
|
int chunkX = event.getChunkX();
|
|
int chunkZ = event.getChunkZ();
|
|
// Modify generation parameters
|
|
});
|
|
|
|
// Post-generation event
|
|
getEventRegistry().register(ChunkGeneratedEvent.class, event -> {
|
|
Chunk chunk = event.getChunk();
|
|
// Post-process chunk
|
|
});
|
|
|
|
// Chunk load event
|
|
getEventRegistry().register(ChunkLoadEvent.class, event -> {
|
|
Chunk chunk = event.getChunk();
|
|
// Handle chunk load
|
|
});
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```yaml
|
|
# worldgen/loader_config.yaml
|
|
WorldLoader:
|
|
ThreadCount: 4
|
|
MaxQueueSize: 1000
|
|
CacheSize: 512
|
|
ViewDistance: 12
|
|
PreloadDistance: 2
|
|
UnloadDelay: 30000
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
{{< callout type="info" >}}
|
|
**Loader Guidelines:**
|
|
- Use appropriate priorities for chunk requests
|
|
- Don't request too many chunks at once
|
|
- Let the cache system handle repeated requests
|
|
- Monitor queue size for performance issues
|
|
{{< /callout >}}
|
|
|
|
{{< callout type="warning" >}}
|
|
**Performance:** Chunk generation is expensive. Avoid:
|
|
- Requesting chunks far from players
|
|
- Bypassing the cache system
|
|
- Blocking on chunk futures on the main thread
|
|
{{< /callout >}}
|