Files
Documentation/content/world/worldgen/chunk-generation.fr.md
2026-01-20 20:33:59 +01:00

5.9 KiB

title, type, weight
title type weight
Génération de Chunks docs 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 :

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

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

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

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 :

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 :

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

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

# 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 >}}