5.6 KiB
5.6 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Chunk Generation | docs | 4 |
Chunk generation handles the block-by-block creation of terrain within each 16x16 chunk.
Package: com.hypixel.hytale.server.worldgen.chunk
ChunkGenerator
The ChunkGenerator creates terrain blocks:
public class ChunkGenerator {
// Generate terrain for chunk
public void generate(GenerationContainer container, int chunkX, int chunkZ);
// Get height at position
public int getHeight(int x, int z);
// Get block at position
public BlockType getBlock(int x, int y, int z);
}
Generation Stages
Chunk generation occurs in stages:
Generation Stages
├── 1. Height Map
│ └── Calculate surface heights
├── 2. Base Terrain
│ └── Fill solid blocks
├── 3. Surface Layer
│ └── Apply biome surface blocks
├── 4. Carving
│ └── Remove blocks for caves/features
└── 5. Decoration
└── Add vegetation, ores, etc.
Height Map Generation
public class HeightMapGenerator {
private NoiseGenerator baseNoise;
private NoiseGenerator detailNoise;
public int getHeight(int x, int z) {
// Base terrain height
float base = baseNoise.noise2D(x * 0.01f, z * 0.01f);
// Detail variation
float detail = detailNoise.noise2D(x * 0.1f, z * 0.1f) * 0.3f;
// Convert to block height
int height = (int) ((base + detail + 1.0f) * 32.0f) + 64;
return Math.clamp(height, 1, 255);
}
}
Terrain Fill
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);
}
}
}
Surface Decoration
public class SurfaceDecorator {
public void decorate(GenerationContainer container, int x, int z) {
int surfaceY = container.getHeight(x, z);
Biome biome = container.getBiome(x, z);
// Add surface features based on biome
for (SurfaceFeature feature : biome.getSurfaceFeatures()) {
if (random.nextFloat() < feature.getDensity()) {
feature.place(container, x, surfaceY + 1, z);
}
}
}
}
Block Palette
Chunks use a block palette for efficient storage:
public class BlockPalette {
private List<BlockType> palette;
private short[] blockData;
// Get block at local position
public BlockType getBlock(int localX, int localY, int localZ) {
int index = localX + localZ * 16 + localY * 256;
short paletteIndex = blockData[index];
return palette.get(paletteIndex);
}
// Set block at local position
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;
}
}
Section-Based Generation
Chunks are divided into 16-block tall sections:
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;
}
}
Ore Generation
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;
// Generate blob of ore blocks
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
Best Practices
{{< callout type="info" >}} Chunk Guidelines:
- Use noise for natural terrain variation
- Apply biome-specific blocks to surfaces
- Generate features after base terrain
- Use palettes for memory efficiency
- Consider section-based optimizations {{< /callout >}}