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