223 lines
5.9 KiB
Markdown
223 lines
5.9 KiB
Markdown
---
|
|
title: Génération de Chunks
|
|
type: docs
|
|
weight: 4
|
|
---
|
|
|
|
La génération de chunks gère la création bloc par bloc du terrain dans chaque chunk 16x16.
|
|
|
|
**Package:** `com.hypixel.hytale.server.worldgen.chunk`
|
|
|
|
## ChunkGenerator
|
|
|
|
Le `ChunkGenerator` crée les blocs de terrain :
|
|
|
|
```java
|
|
public class ChunkGenerator {
|
|
// Générer le terrain pour un chunk
|
|
public void generate(GenerationContainer container, int chunkX, int chunkZ);
|
|
|
|
// Obtenir la hauteur à une position
|
|
public int getHeight(int x, int z);
|
|
|
|
// Obtenir le bloc à une position
|
|
public BlockType getBlock(int x, int y, int z);
|
|
}
|
|
```
|
|
|
|
## Étapes de Génération
|
|
|
|
La génération de chunk se fait par étapes :
|
|
|
|
```
|
|
Étapes de Génération
|
|
├── 1. Carte de Hauteur
|
|
│ └── Calculer les hauteurs de surface
|
|
├── 2. Terrain de Base
|
|
│ └── Remplir les blocs solides
|
|
├── 3. Couche de Surface
|
|
│ └── Appliquer les blocs de surface du biome
|
|
├── 4. Creusement
|
|
│ └── Supprimer les blocs pour grottes/features
|
|
└── 5. Décoration
|
|
└── Ajouter végétation, minerais, etc.
|
|
```
|
|
|
|
## Génération de Carte de Hauteur
|
|
|
|
```java
|
|
public class HeightMapGenerator {
|
|
private NoiseGenerator baseNoise;
|
|
private NoiseGenerator detailNoise;
|
|
|
|
public int getHeight(int x, int z) {
|
|
// Hauteur de terrain de base
|
|
float base = baseNoise.noise2D(x * 0.01f, z * 0.01f);
|
|
|
|
// Variation de détail
|
|
float detail = detailNoise.noise2D(x * 0.1f, z * 0.1f) * 0.3f;
|
|
|
|
// Convertir en hauteur de bloc
|
|
int height = (int) ((base + detail + 1.0f) * 32.0f) + 64;
|
|
return Math.clamp(height, 1, 255);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Remplissage du Terrain
|
|
|
|
```java
|
|
public class TerrainFiller {
|
|
public void fill(GenerationContainer container, int x, int z, int height) {
|
|
Biome biome = container.getBiome(x, z);
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
BlockType block;
|
|
|
|
if (y == 0) {
|
|
block = BlockTypes.BEDROCK;
|
|
} else if (y < height - 4) {
|
|
block = biome.getStoneBlock();
|
|
} else if (y < height - 1) {
|
|
block = biome.getSubsurfaceBlock();
|
|
} else {
|
|
block = biome.getSurfaceBlock();
|
|
}
|
|
|
|
container.setBlock(x, y, z, block);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Décoration de Surface
|
|
|
|
```java
|
|
public class SurfaceDecorator {
|
|
public void decorate(GenerationContainer container, int x, int z) {
|
|
int surfaceY = container.getHeight(x, z);
|
|
Biome biome = container.getBiome(x, z);
|
|
|
|
// Ajouter des features de surface selon le biome
|
|
for (SurfaceFeature feature : biome.getSurfaceFeatures()) {
|
|
if (random.nextFloat() < feature.getDensity()) {
|
|
feature.place(container, x, surfaceY + 1, z);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Palette de Blocs
|
|
|
|
Les chunks utilisent une palette de blocs pour un stockage efficace :
|
|
|
|
```java
|
|
public class BlockPalette {
|
|
private List<BlockType> palette;
|
|
private short[] blockData;
|
|
|
|
// Obtenir le bloc à une position locale
|
|
public BlockType getBlock(int localX, int localY, int localZ) {
|
|
int index = localX + localZ * 16 + localY * 256;
|
|
short paletteIndex = blockData[index];
|
|
return palette.get(paletteIndex);
|
|
}
|
|
|
|
// Définir le bloc à une position locale
|
|
public void setBlock(int localX, int localY, int localZ, BlockType type) {
|
|
int index = localX + localZ * 16 + localY * 256;
|
|
int paletteIndex = palette.indexOf(type);
|
|
if (paletteIndex == -1) {
|
|
paletteIndex = palette.size();
|
|
palette.add(type);
|
|
}
|
|
blockData[index] = (short) paletteIndex;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Génération par Sections
|
|
|
|
Les chunks sont divisés en sections de 16 blocs de haut :
|
|
|
|
```java
|
|
public class ChunkSection {
|
|
private static final int SIZE = 16 * 16 * 16;
|
|
private BlockPalette palette;
|
|
private byte[] lightData;
|
|
|
|
public boolean isEmpty() {
|
|
return palette.size() == 1 && palette.get(0) == BlockTypes.AIR;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Génération de Minerais
|
|
|
|
```java
|
|
public class OreGenerator {
|
|
public void generateOres(GenerationContainer container, int chunkX, int chunkZ) {
|
|
for (OreConfig ore : oreConfigs) {
|
|
int count = random.nextInt(ore.maxVeins - ore.minVeins) + ore.minVeins;
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
int x = chunkX * 16 + random.nextInt(16);
|
|
int y = random.nextInt(ore.maxY - ore.minY) + ore.minY;
|
|
int z = chunkZ * 16 + random.nextInt(16);
|
|
|
|
generateOreVein(container, x, y, z, ore);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void generateOreVein(GenerationContainer container, int x, int y, int z, OreConfig ore) {
|
|
int size = random.nextInt(ore.maxSize - ore.minSize) + ore.minSize;
|
|
// Générer une grappe de blocs de minerai
|
|
for (int i = 0; i < size; i++) {
|
|
int dx = random.nextInt(3) - 1;
|
|
int dy = random.nextInt(3) - 1;
|
|
int dz = random.nextInt(3) - 1;
|
|
if (container.getBlock(x + dx, y + dy, z + dz) == ore.replaceBlock) {
|
|
container.setBlock(x + dx, y + dy, z + dz, ore.oreBlock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```yaml
|
|
# worldgen/chunk_config.yaml
|
|
ChunkGeneration:
|
|
HeightNoise:
|
|
Octaves: 6
|
|
Persistence: 0.5
|
|
Scale: 0.01
|
|
SeaLevel: 64
|
|
BedrockLayers: 5
|
|
Ores:
|
|
- Type: iron_ore
|
|
MinY: 0
|
|
MaxY: 64
|
|
VeinsPerChunk: 20
|
|
VeinSize: 9
|
|
- Type: diamond_ore
|
|
MinY: 0
|
|
MaxY: 16
|
|
VeinsPerChunk: 1
|
|
VeinSize: 8
|
|
```
|
|
|
|
## Bonnes Pratiques
|
|
|
|
{{< callout type="info" >}}
|
|
**Directives des Chunks :**
|
|
- Utilisez le bruit pour une variation de terrain naturelle
|
|
- Appliquez des blocs spécifiques au biome sur les surfaces
|
|
- Générez les features après le terrain de base
|
|
- Utilisez des palettes pour l'efficacité mémoire
|
|
- Considérez les optimisations basées sur les sections
|
|
{{< /callout >}}
|