feat(world-gen): larger biomes, smooth height blending, capped mountains; centralize tunables in Configuration
Terrain feel: biome regions ~10x larger (Voronoi cell size 96->960); terrain height now eases across biome borders via a Voronoi distance blend (smooth, and ~25x cheaper than the old 169-sample box blur); mountains capped to ~2/3 world height and gentled (ridged amplitude/frequency lowered), snow line lowered to match. Centralization: ~27 world-gen/render tuning constants (biome amplitudes & frequencies, climate-noise frequencies/octaves, biome-selection thresholds, blend width, cell size, filler depth, snow line, camera near plane, spawn offset, overlay scale) hoisted from scattered literals into a region-organized, fully-commented Configuration. Configuration is threaded into NoiseSource, the biomes, BiomeRegistry, BiomeMap (+Classify), TerrainSampler, WorldGenerator (+BlockAt filler depth), and Camera via Player. Defaults equal the prior values, so generation is unchanged; worldgen tests updated for the new constructor signatures.
This commit is contained in:
@@ -7,9 +7,7 @@ namespace VoxelEngine.World.WorldGen;
|
||||
|
||||
public sealed class WorldGenerator
|
||||
{
|
||||
private const int FillerDepth = 3;
|
||||
private const float CellSize = 96f;
|
||||
|
||||
private readonly Configuration _cfg;
|
||||
private readonly BlockRegistry _blocks;
|
||||
private readonly BiomeMap _biomeMap;
|
||||
private readonly TerrainSampler _terrain;
|
||||
@@ -17,17 +15,20 @@ public sealed class WorldGenerator
|
||||
|
||||
public WorldGenerator(int seed, BlockRegistry blocks, Configuration cfg)
|
||||
{
|
||||
this._cfg = cfg;
|
||||
this._blocks = blocks;
|
||||
NoiseSource noise = new(seed);
|
||||
VoronoiCells cells = new(seed, WorldGenerator.CellSize);
|
||||
BiomeRegistry biomes = new(seed, blocks);
|
||||
this._biomeMap = new BiomeMap(noise, cells, biomes);
|
||||
this._terrain = new TerrainSampler(noise, this._biomeMap);
|
||||
NoiseSource noise = new(seed, cfg);
|
||||
VoronoiCells cells = new(seed, cfg.BiomeCellSize);
|
||||
BiomeRegistry biomes = new(seed, blocks, cfg);
|
||||
this._biomeMap = new BiomeMap(noise, cells, biomes, cfg);
|
||||
this._terrain = new TerrainSampler(noise, this._biomeMap, cfg);
|
||||
this._caves = new CaveCarver(seed, blocks, cfg);
|
||||
}
|
||||
|
||||
public int SurfaceHeightAt(int worldX, int worldZ) => this._terrain.HeightAt(worldX, worldZ);
|
||||
|
||||
public string BiomeNameAt(int worldX, int worldZ) => this._biomeMap.BiomeAt(worldX, worldZ).Name;
|
||||
|
||||
public VoxelChunk Generate(Vector3i chunkPos)
|
||||
{
|
||||
VoxelChunk chunk = new();
|
||||
@@ -46,7 +47,7 @@ public sealed class WorldGenerator
|
||||
for (int y = 0; y < VoxelChunk.Size; y++)
|
||||
{
|
||||
int worldY = baseY + y;
|
||||
chunk[x, y, z] = WorldGenerator.BlockAt(worldY, height, biome, this._blocks);
|
||||
chunk[x, y, z] = BlockAt(worldY, height, biome, this._blocks, this._cfg.SurfaceFillerDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,13 +55,13 @@ public sealed class WorldGenerator
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public static ushort BlockAt(int worldY, int surfaceHeight, IBiome biome, BlockRegistry blocks)
|
||||
public static ushort BlockAt(int worldY, int surfaceHeight, IBiome biome, BlockRegistry blocks, int fillerDepth)
|
||||
{
|
||||
if (worldY > surfaceHeight)
|
||||
return worldY <= WorldConstants.SeaLevel ? blocks.Water.Id : blocks.Air.Id;
|
||||
if (worldY == surfaceHeight)
|
||||
return biome.TopBlock(worldY).Id;
|
||||
if (worldY >= surfaceHeight - WorldGenerator.FillerDepth)
|
||||
if (worldY >= surfaceHeight - fillerDepth)
|
||||
return biome.Surface.Filler.Id;
|
||||
return biome.Surface.Under.Id;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user