100 lines
3.3 KiB
C#
100 lines
3.3 KiB
C#
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(80, surfaceHeight: 70, biomes.Plains, blocks);
|
|
Assert.Equal(blocks.Air.Id, id); // 80 > 70 and 80 > SeaLevel(64)
|
|
}
|
|
|
|
[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]);
|
|
}
|
|
}
|