using OpenTK.Mathematics; using VoxelEngine.Core; using VoxelEngine.World.Blocks; using VoxelEngine.World.Chunk; using VoxelEngine.World.WorldGen; using Xunit; namespace VoxelEngine.Tests.WorldGen; public class WorldGeneratorTests { private static BlockRegistry Blocks => new(); [Fact] public void BlockAt_AboveTerrainAndSea_IsAir() { var blocks = Blocks; var biomes = new BiomeRegistry(1, blocks); ushort id = WorldGenerator.BlockAt(300, surfaceHeight: 290, biomes.Plains, blocks); Assert.Equal(blocks.Air.Id, id); // 300 > 290 (above surface) and 300 > SeaLevel(256) } [Fact] public void BlockAt_AboveTerrainBelowSea_IsWater() { var blocks = Blocks; var biomes = new BiomeRegistry(1, blocks); ushort id = WorldGenerator.BlockAt(60, surfaceHeight: 50, biomes.Plains, blocks); Assert.Equal(blocks.Water.Id, id); // 60 > 50 but 60 <= SeaLevel(64) } [Fact] public void BlockAt_Surface_IsBiomeTop() { var blocks = Blocks; var biomes = new BiomeRegistry(1, blocks); ushort id = WorldGenerator.BlockAt(70, surfaceHeight: 70, biomes.Desert, blocks); Assert.Equal(blocks.Sand.Id, id); } [Fact] public void BlockAt_FillerBand_IsBiomeFiller() { var blocks = Blocks; var biomes = new BiomeRegistry(1, blocks); ushort id = WorldGenerator.BlockAt(68, surfaceHeight: 70, biomes.Plains, blocks); Assert.Equal(blocks.Dirt.Id, id); // within 3 of surface } [Fact] public void BlockAt_Deep_IsStone() { var blocks = Blocks; var biomes = new BiomeRegistry(1, blocks); ushort id = WorldGenerator.BlockAt(40, surfaceHeight: 70, biomes.Plains, blocks); Assert.Equal(blocks.Stone.Id, id); } [Fact] public void Generate_IsDeterministic() { var gen1 = new WorldGenerator(99, Blocks, new Configuration()); var gen2 = new WorldGenerator(99, Blocks, new Configuration()); Chunk a = gen1.Generate(new Vector3i(0, 4, 0)); Chunk b = gen2.Generate(new Vector3i(0, 4, 0)); for (int x = 0; x < Chunk.Size; x++) for (int y = 0; y < Chunk.Size; y++) for (int z = 0; z < Chunk.Size; z++) Assert.Equal(a[x, y, z], b[x, y, z]); } [Fact] public void Generate_AppliesCaves_ProducesAirVoxelsBelowSurface() { var gen = new WorldGenerator(seed: 12345, Blocks, new Configuration()); // A chunk well below typical surface height — guaranteed mostly stone before carving. Chunk c = gen.Generate(new Vector3i(0, 1, 0)); // worldY = 16..31 int airCount = 0; for (int x = 0; x < Chunk.Size; x++) for (int y = 0; y < Chunk.Size; y++) for (int z = 0; z < Chunk.Size; z++) if (c[x, y, z] == Blocks.Air.Id) airCount++; Assert.True(airCount > 0, "Deep chunk had zero air voxels after generation — caves not running?"); } [Fact] public void Generate_PreservesBedrockFloor_Y0_IsStone() { var gen = new WorldGenerator(seed: 12345, Blocks, new Configuration()); Chunk c = gen.Generate(new Vector3i(0, 0, 0)); // worldY = 0..15 for (int x = 0; x < Chunk.Size; x++) for (int z = 0; z < Chunk.Size; z++) Assert.Equal(Blocks.Stone.Id, c[x, 0, z]); } }