Files
VoxelEngine/Core/Configuration.cs
MDietermann e034d10339 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.
2026-06-03 16:27:06 +02:00

209 lines
8.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace VoxelEngine.Core;
using OpenTK.Mathematics;
public sealed class Configuration
{
#region -- World --
// World generation seed. null → a fresh random seed each run; set a value for
// a reproducible world.
public int? Seed { get; set; } = null;
// Blocks above the terrain surface at (0,0) where the player spawns.
public float SpawnHeightOffset { get; set; } = 2f;
#endregion -- World --
#region -- Rendering & View --
// Horizontal view radius in chunks (Chebyshev). Drives how far terrain loads
// and the fog / far-plane distance. Higher = see further, much heavier load.
public int RenderDistanceHorizontal { get; set; } = 8;
// Camera vertical field of view, in degrees.
public float Fov { get; set; } = 60f;
// Near clip plane distance (world units); anything nearer is not drawn.
// (The far plane is derived from RenderDistanceHorizontal over in Player.)
public float CameraNearPlane { get; set; } = 0.1f;
// Distance fog begins at this fraction of the fog-end distance (fog end is
// derived from RenderDistanceHorizontal). 0.7 → fog starts at 70% of the edge.
public float FogStartFraction { get; set; } = 0.7f;
// Sky / clear colour, also the distance-fog target colour (RGB, 0–1).
public Vector3 SkyColor { get; set; } = new(0.45f, 0.65f, 0.95f);
#endregion -- Rendering & View --
#region -- Window --
// Initial window size in pixels.
public int WindowWidth { get; set; } = 1280;
public int WindowHeight { get; set; } = 720;
#endregion -- Window --
#region -- Chunk Streaming --
// Horizontal radius (chunks) around spawn that must finish loading before the
// loading screen clears.
public int SpawnReadyRadiusHorizontal { get; set; } = 1;
// Max chunk generate/mesh jobs running on worker threads at once.
public int MaxGenerateJobsInFlight { get; set; } = 8;
// Max finished chunk meshes uploaded to the GPU per frame (caps per-frame hitches).
public int MaxMeshUploadsPerFrame { get; set; } = 4;
// Background worker threads used for chunk generation/meshing.
public int WorkerThreadCount { get; set; } = Math.Max(1, Environment.ProcessorCount / 2);
// Multiplier applied to (dy)² in chunk-load priority. >1 prioritizes chunks at
// the player's Y over equally-distant chunks above/below, so the visible
// surface fills in before far-underground / overhead chunks.
public int VerticalPriorityWeight { get; set; } = 4;
#endregion -- Chunk Streaming --
#region -- Player & Controls --
// Movement speed, in blocks per second.
public float MoveSpeed { get; set; } = 8f;
// Mouse-look sensitivity (degrees of rotation per pixel of mouse movement).
public float MouseSensitivity { get; set; } = 0.15f;
#endregion -- Player & Controls --
#region -- World Gen: Terrain Shape --
// Average width in blocks of one biome region (Voronoi cell). Larger = bigger,
// fewer biomes.
public float BiomeCellSize { get; set; } = 960f;
// Blocks over which terrain height eases from one biome to its neighbour across
// their shared border. Larger = gentler, wider transitions.
public float BiomeBlendWidth { get; set; } = 128f;
// Filler layers (dirt/sand) placed directly below the surface block before the
// biome's solid under-material (usually stone) begins.
public int SurfaceFillerDepth { get; set; } = 3;
#endregion -- World Gen: Terrain Shape --
#region -- World Gen: Climate Noise --
// Low-frequency fields that decide biome placement. Lower frequency = larger,
// smoother climate regions; more octaves = more fine variation.
// Elevation field — high values become Mountains, low values lowland.
public float ContinentFrequency { get; set; } = 0.0035f;
public int ContinentOctaves { get; set; } = 4;
// Temperature field — high values become Desert.
public float TemperatureFrequency { get; set; } = 0.0015f;
public int TemperatureOctaves { get; set; } = 3;
// Forest-density field — high values become Forest (else Plains).
public float ForestFrequency { get; set; } = 0.02f;
#endregion -- World Gen: Climate Noise --
#region -- World Gen: Biome Selection --
// Thresholds on the climate fields (values ≈ -1..1), tested in order:
// mountains → desert → forest → plains.
// Elevation at/above which a cell is Mountains.
public float MountainsElevationThreshold { get; set; } = 0.25f;
// Temperature above which a non-mountain cell is Desert.
public float DesertTemperatureThreshold { get; set; } = 0.33f;
// Minimum temperature for Forest (colder than this → Plains).
public float ForestTemperatureThreshold { get; set; } = -0.33f;
// Minimum forest-density for Forest (below this → Plains).
public float ForestDensityThreshold { get; set; } = 0f;
#endregion -- World Gen: Biome Selection --
#region -- World Gen: Biome Surface Heights --
// Per biome: surfaceHeight = SeaLevel + ContinentAmplitude·continentNoise
// + DetailAmplitude·detailNoise. Amplitudes are in blocks; detail frequency
// sets the bumpiness scale (higher = smaller, choppier features).
// Plains — gentle rolling grassland.
public float PlainsContinentAmplitude { get; set; } = 24f;
public float PlainsDetailAmplitude { get; set; } = 8f;
public float PlainsDetailFrequency { get; set; } = 0.01f;
// Forest — like plains, a touch hillier.
public float ForestContinentAmplitude { get; set; } = 24f;
public float ForestDetailAmplitude { get; set; } = 16f;
public float ForestDetailFrequency { get; set; } = 0.01f;
// Desert — flat with low dunes.
public float DesertContinentAmplitude { get; set; } = 16f;
public float DesertDetailAmplitude { get; set; } = 6f;
public float DesertDetailFrequency { get; set; } = 0.008f;
// Mountains — tall ridged peaks (uses ridged noise instead of a smooth detail
// field). Peaks roughly cap at SeaLevel + ContinentAmplitude + RidgedAmplitude.
public float MountainsContinentAmplitude { get; set; } = 40f;
public float MountainsRidgedAmplitude { get; set; } = 45f;
public float MountainsRidgedFrequency { get; set; } = 0.005f;
public int MountainsRidgedOctaves { get; set; } = 4;
// World-Y at/above which mountain tops render as snow.
public int MountainsSnowLine { get; set; } = 270;
#endregion -- World Gen: Biome Surface Heights --
#region -- Cave Generation --
// Spatial frequency of the 3D simplex cave-density field; higher = smaller,
// more frequent pockets.
public float CaveNoiseFrequency { get; set; } = 0.03f;
// Density cutoff below which a solid voxel becomes air; higher = more cave.
public float CaveNoiseThreshold { get; set; } = -0.3f;
// Edge length (blocks) of a worm-spawn grid cell; one worm candidate per cell.
public int WormCellSize { get; set; } = 64;
// Per-cell chance out of 1000 that a worm spawns; 300 = 30%.
public int WormSpawnProbabilityPermille { get; set; } = 300;
// Number of trace steps (≈ blocks) a worm travels.
public int WormMaxLength { get; set; } = 80;
// Worm tunnel radius bounds; interpolated + sine-modulated along the path to
// form bulges/chambers.
public float WormMinRadius { get; set; } = 1.5f;
public float WormMaxRadius { get; set; } = 3.5f;
// Ceiling: caves carve only at or below this world-Y ("no caves above").
// Default 256 = SeaLevel → caves stay below sea level, keeping the taller
// surface terrain solid. Raise toward WorldHeight-1 to allow surface caves.
public int MinCaveY { get; set; } = 256;
#endregion -- Cave Generation --
#region -- Cave Lighting --
// Underground darkening: brightness fades from CaveDarkStartY down to
// CaveDarkEndY, never dropping below CaveMinBrightness.
public float CaveDarkStartY { get; set; } = 264f; // WorldConstants.SeaLevel + 8
public float CaveDarkEndY { get; set; } = 224f; // WorldConstants.SeaLevel - 32
public float CaveMinBrightness { get; set; } = 0.15f; // floor brightness deep underground (0–1)
#endregion -- Cave Lighting --
#region -- Debug Overlay --
// Pixel size of each font "pixel" in the on-screen debug text (biome + coords).
public int DebugOverlayTextScale { get; set; } = 3;
#endregion -- Debug Overlay --
}