Init
This commit is contained in:
222
content/world/worldgen/chunk-generation.en.md
Normal file
222
content/world/worldgen/chunk-generation.en.md
Normal file
@@ -0,0 +1,222 @@
|
||||
---
|
||||
title: Chunk Generation
|
||||
type: docs
|
||||
weight: 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:
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```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);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Surface Decoration
|
||||
|
||||
```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);
|
||||
|
||||
// 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:
|
||||
|
||||
```java
|
||||
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:
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Ore Generation
|
||||
|
||||
```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;
|
||||
// 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
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## 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 >}}
|
||||
Reference in New Issue
Block a user