242 lines
6.0 KiB
Markdown
242 lines
6.0 KiB
Markdown
---
|
|
title: World Loader
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
Le système World Loader gère le chargement des chunks, la planification de génération et le streaming du monde.
|
|
|
|
**Package:** `com.hypixel.hytale.server.worldgen.loader`
|
|
|
|
## Classe WorldLoader
|
|
|
|
Le `WorldLoader` coordonne le chargement et la génération des chunks :
|
|
|
|
```java
|
|
public class WorldLoader {
|
|
// Charger un chunk aux coordonnées
|
|
public CompletableFuture<Chunk> loadChunk(int chunkX, int chunkZ);
|
|
|
|
// Décharger un chunk
|
|
public void unloadChunk(int chunkX, int chunkZ);
|
|
|
|
// Vérifier si un chunk est chargé
|
|
public boolean isChunkLoaded(int chunkX, int chunkZ);
|
|
|
|
// Obtenir un chunk chargé
|
|
public Chunk getChunk(int chunkX, int chunkZ);
|
|
|
|
// Demander la génération d'un chunk
|
|
public void requestGeneration(int chunkX, int chunkZ, int priority);
|
|
}
|
|
```
|
|
|
|
## Pipeline de Chargement
|
|
|
|
Le processus de chargement de chunk suit plusieurs étapes :
|
|
|
|
```
|
|
Pipeline de Chargement de Chunk
|
|
├── 1. Vérifier le Cache
|
|
│ └── Retourner si en cache
|
|
├── 2. Charger depuis le Disque
|
|
│ └── Retourner si sauvegardé
|
|
├── 3. Mettre en Queue pour Génération
|
|
│ ├── Attribution de Priorité
|
|
│ └── Dispatch Thread Pool
|
|
├── 4. Générer le Chunk
|
|
│ ├── Passe Terrain
|
|
│ ├── Passe Grottes
|
|
│ ├── Passe Structures
|
|
│ └── Passe Décoration
|
|
└── 5. Mettre en Cache et Retourner
|
|
```
|
|
|
|
## 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
|
|
}
|
|
}
|
|
```
|
|
|
|
## Système de Priorité de Chargement
|
|
|
|
Les chunks sont chargés selon leur priorité :
|
|
|
|
```java
|
|
public class LoadPriority {
|
|
// Priorité la plus haute - chunk actuel du joueur
|
|
public static final int IMMEDIATE = 0;
|
|
|
|
// Haute priorité - chunks autour du joueur
|
|
public static final int PLAYER_VIEW = 100;
|
|
|
|
// Priorité normale - besoins des entités
|
|
public static final int ENTITY = 200;
|
|
|
|
// Basse priorité - préchargement
|
|
public static final int PRELOAD = 300;
|
|
|
|
// Priorité la plus basse - tâches de fond
|
|
public static final int BACKGROUND = 400;
|
|
}
|
|
```
|
|
|
|
## Threading de Génération
|
|
|
|
La génération de monde utilise un pool de threads :
|
|
|
|
```java
|
|
public class GenerationThreadPool {
|
|
private int threadCount;
|
|
private PriorityBlockingQueue<ChunkLoadRequest> queue;
|
|
|
|
// Configurer le nombre de threads
|
|
public void setThreadCount(int count);
|
|
|
|
// Obtenir la taille de la queue
|
|
public int getPendingCount();
|
|
|
|
// Effacer les requêtes basse priorité
|
|
public void clearLowPriority(int threshold);
|
|
}
|
|
```
|
|
|
|
## Cache de Chunks
|
|
|
|
Le loader maintient un cache de chunks :
|
|
|
|
```java
|
|
public class ChunkCache {
|
|
private int maxSize;
|
|
private Map<ChunkPos, Chunk> cache;
|
|
|
|
// Obtenir un chunk en cache
|
|
public Chunk get(int chunkX, int chunkZ);
|
|
|
|
// Ajouter au cache
|
|
public void put(int chunkX, int chunkZ, Chunk chunk);
|
|
|
|
// Supprimer du cache
|
|
public void invalidate(int chunkX, int chunkZ);
|
|
|
|
// Vider le cache
|
|
public void clear();
|
|
|
|
// Obtenir les statistiques du cache
|
|
public CacheStats getStats();
|
|
}
|
|
```
|
|
|
|
## Chargement par Distance de Vue
|
|
|
|
```java
|
|
public class ViewDistanceLoader {
|
|
private int viewDistance;
|
|
private Player player;
|
|
|
|
// Mettre à jour les chunks chargés pour un joueur
|
|
public void updatePlayerChunks(Player player) {
|
|
Vector3d pos = player.getPosition();
|
|
int centerX = (int) pos.x >> 4;
|
|
int centerZ = (int) pos.z >> 4;
|
|
|
|
// Charger les chunks dans la distance de vue
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Système de Conteneurs
|
|
|
|
Les conteneurs de génération gèrent les données intermédiaires :
|
|
|
|
```java
|
|
public class GenerationContainer {
|
|
private int chunkX;
|
|
private int chunkZ;
|
|
private BlockBuffer blockBuffer;
|
|
private BiomeMap biomeMap;
|
|
private HeightMap heightMap;
|
|
|
|
// Définir un bloc dans le conteneur
|
|
public void setBlock(int x, int y, int z, BlockType type);
|
|
|
|
// Obtenir un bloc du conteneur
|
|
public BlockType getBlock(int x, int y, int z);
|
|
|
|
// Finaliser en chunk
|
|
public Chunk toChunk();
|
|
}
|
|
```
|
|
|
|
## Hooks d'Événements
|
|
|
|
```java
|
|
// Événement pré-génération
|
|
getEventRegistry().register(ChunkPreGenerateEvent.class, event -> {
|
|
int chunkX = event.getChunkX();
|
|
int chunkZ = event.getChunkZ();
|
|
// Modifier les paramètres de génération
|
|
});
|
|
|
|
// Événement post-génération
|
|
getEventRegistry().register(ChunkGeneratedEvent.class, event -> {
|
|
Chunk chunk = event.getChunk();
|
|
// Post-traiter le chunk
|
|
});
|
|
|
|
// Événement de chargement de chunk
|
|
getEventRegistry().register(ChunkLoadEvent.class, event -> {
|
|
Chunk chunk = event.getChunk();
|
|
// Gérer le chargement du chunk
|
|
});
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```yaml
|
|
# worldgen/loader_config.yaml
|
|
WorldLoader:
|
|
ThreadCount: 4
|
|
MaxQueueSize: 1000
|
|
CacheSize: 512
|
|
ViewDistance: 12
|
|
PreloadDistance: 2
|
|
UnloadDelay: 30000
|
|
```
|
|
|
|
## Bonnes Pratiques
|
|
|
|
{{< callout type="info" >}}
|
|
**Directives du Loader :**
|
|
- Utilisez des priorités appropriées pour les requêtes de chunks
|
|
- Ne demandez pas trop de chunks à la fois
|
|
- Laissez le système de cache gérer les requêtes répétées
|
|
- Surveillez la taille de la queue pour les problèmes de performance
|
|
{{< /callout >}}
|
|
|
|
{{< callout type="warning" >}}
|
|
**Performance :** La génération de chunks est coûteuse. Évitez :
|
|
- De demander des chunks loin des joueurs
|
|
- De contourner le système de cache
|
|
- De bloquer sur les futures de chunks sur le thread principal
|
|
{{< /callout >}}
|