Fix deterministic terrain generation

This commit is contained in:
Drew DeVault 2017-05-23 19:54:04 -04:00
parent c5c0e5ddf4
commit 05a6b10e21
12 changed files with 55 additions and 39 deletions

View File

@ -11,5 +11,6 @@ namespace TrueCraft.API.World
IList<IChunkDecorator> ChunkDecorators { get; } IList<IChunkDecorator> ChunkDecorators { get; }
IChunk GenerateChunk(IWorld world, Coordinates2D coordinates); IChunk GenerateChunk(IWorld world, Coordinates2D coordinates);
Coordinates3D GetSpawn(IWorld world); Coordinates3D GetSpawn(IWorld world);
void Initialize(IWorld world);
} }
} }

View File

@ -15,8 +15,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{ {
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
{ {
var noise = new Perlin(); var noise = new Perlin(world.Seed);
noise.Seed = world.Seed;
var chanceNoise = new ClampNoise(noise); var chanceNoise = new ClampNoise(noise);
chanceNoise.MaxValue = 2; chanceNoise.MaxValue = 2;
for (int x = 0; x < 16; x++) for (int x = 0; x < 16; x++)

View File

@ -55,12 +55,10 @@ namespace TrueCraft.Core.TerrainGen.Decorators
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
{ {
//Test Seed: 291887241 var perlin = new Perlin(world.Seed);
var perlin = new Perlin();
perlin.Lacunarity = 1; perlin.Lacunarity = 1;
perlin.Amplitude = 7; perlin.Amplitude = 7;
perlin.Frequency = 0.015; perlin.Frequency = 0.015;
perlin.Seed = world.Seed;
var chanceNoise = new ClampNoise(perlin); var chanceNoise = new ClampNoise(perlin);
var noise = new ScaledNoise(perlin); var noise = new ScaledNoise(perlin);
var random = new Random(world.Seed); var random = new Random(world.Seed);

View File

@ -14,8 +14,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{ {
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
{ {
var noise = new Perlin(); var noise = new Perlin(world.Seed);
noise.Seed = world.Seed;
var chanceNoise = new ClampNoise(noise); var chanceNoise = new ClampNoise(noise);
chanceNoise.MaxValue = 2; chanceNoise.MaxValue = 2;
for (int x = 0; x < 16; x++) for (int x = 0; x < 16; x++)

View File

@ -15,8 +15,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{ {
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
{ {
var noise = new Perlin(); var noise = new Perlin(world.Seed);
noise.Seed = world.Seed;
var chanceNoise = new ClampNoise(noise); var chanceNoise = new ClampNoise(noise);
chanceNoise.MaxValue = 1; chanceNoise.MaxValue = 1;
for (int x = 0; x < 16; x++) for (int x = 0; x < 16; x++)

View File

@ -18,8 +18,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
{ {
Noise = new Perlin(); Noise = new Perlin(world.Seed);
Noise.Seed = world.Seed;
ChanceNoise = new ClampNoise(Noise); ChanceNoise = new ClampNoise(Noise);
ChanceNoise.MaxValue = 2; ChanceNoise.MaxValue = 2;
Coordinates2D? lastTree = null; Coordinates2D? lastTree = null;

View File

@ -8,10 +8,6 @@ namespace TrueCraft.Core
{ {
public class EmptyGenerator : IChunkProvider public class EmptyGenerator : IChunkProvider
{ {
public EmptyGenerator()
{
}
public IChunk GenerateChunk(IWorld world, Coordinates2D coordinates) public IChunk GenerateChunk(IWorld world, Coordinates2D coordinates)
{ {
return new Chunk(coordinates); return new Chunk(coordinates);
@ -22,6 +18,10 @@ namespace TrueCraft.Core
return Coordinates3D.Zero; return Coordinates3D.Zero;
} }
public void Initialize(IWorld world)
{
}
public IList<IChunkDecorator> ChunkDecorators { get; set; } public IList<IChunkDecorator> ChunkDecorators { get; set; }
} }
} }

View File

@ -27,6 +27,10 @@ namespace TrueCraft.Core.TerrainGen
GeneratorOptions = generatorOptions; GeneratorOptions = generatorOptions;
} }
public void Initialize(IWorld world)
{
}
public static string DefaultGeneratorOptions { get; set; } public static string DefaultGeneratorOptions { get; set; }
public string GeneratorOptions public string GeneratorOptions

View File

@ -16,7 +16,7 @@ namespace TrueCraft.Core.TerrainGen.Noise
public double Lacunarity { get; set; } public double Lacunarity { get; set; }
public InterpolateType Interpolation { get; set; } public InterpolateType Interpolation { get; set; }
public Perlin(int seed = 0) public Perlin(int seed)
{ {
this.Seed = seed; this.Seed = seed;
this.Octaves = 2; this.Octaves = 2;

View File

@ -19,10 +19,10 @@ namespace TrueCraft.Core.TerrainGen
public class StandardGenerator : IChunkProvider public class StandardGenerator : IChunkProvider
{ {
BiomeRepository Biomes = new BiomeRepository(); BiomeRepository Biomes = new BiomeRepository();
Perlin HighNoise = new Perlin(); Perlin HighNoise;
Perlin LowNoise = new Perlin(); Perlin LowNoise;
Perlin BottomNoise = new Perlin(); Perlin BottomNoise;
Perlin CaveNoise = new Perlin(); Perlin CaveNoise;
ClampNoise HighClamp; ClampNoise HighClamp;
ClampNoise LowClamp; ClampNoise LowClamp;
ClampNoise BottomClamp; ClampNoise BottomClamp;
@ -30,10 +30,27 @@ namespace TrueCraft.Core.TerrainGen
bool EnableCaves; bool EnableCaves;
private const int GroundLevel = 50; private const int GroundLevel = 50;
public StandardGenerator(IWorld world) public StandardGenerator()
{ {
EnableCaves = true; EnableCaves = true;
ChunkDecorators = new List<IChunkDecorator>();
ChunkDecorators.Add(new LiquidDecorator());
ChunkDecorators.Add(new OreDecorator());
ChunkDecorators.Add(new PlantDecorator());
ChunkDecorators.Add(new TreeDecorator());
ChunkDecorators.Add(new FreezeDecorator());
ChunkDecorators.Add(new CactusDecorator());
ChunkDecorators.Add(new SugarCaneDecorator());
ChunkDecorators.Add(new DungeonDecorator(GroundLevel));
}
public void Initialize(IWorld world)
{
HighNoise = new Perlin(world.Seed);
LowNoise = new Perlin(world.Seed);
BottomNoise = new Perlin(world.Seed);
CaveNoise = new Perlin(world.Seed);
CaveNoise.Octaves = 3; CaveNoise.Octaves = 3;
CaveNoise.Amplitude = 0.05; CaveNoise.Amplitude = 0.05;
CaveNoise.Persistance = 2; CaveNoise.Persistance = 2;
@ -71,16 +88,6 @@ namespace TrueCraft.Core.TerrainGen
BottomClamp.MaxValue = 5; BottomClamp.MaxValue = 5;
FinalNoise = new ModifyNoise(HighClamp, LowClamp, NoiseModifier.Add); FinalNoise = new ModifyNoise(HighClamp, LowClamp, NoiseModifier.Add);
ChunkDecorators = new List<IChunkDecorator>();
ChunkDecorators.Add(new LiquidDecorator());
ChunkDecorators.Add(new OreDecorator());
ChunkDecorators.Add(new PlantDecorator());
ChunkDecorators.Add(new TreeDecorator());
ChunkDecorators.Add(new FreezeDecorator());
ChunkDecorators.Add(new CactusDecorator());
ChunkDecorators.Add(new SugarCaneDecorator());
ChunkDecorators.Add(new DungeonDecorator(GroundLevel));
} }
public IList<IChunkDecorator> ChunkDecorators { get; private set; } public IList<IChunkDecorator> ChunkDecorators { get; private set; }
@ -221,4 +228,4 @@ namespace TrueCraft.Core.TerrainGen
return (int)value; return (int)value;
} }
} }
} }

View File

@ -12,11 +12,12 @@ namespace TrueCraft.Core.World
{ {
public IList<BiomeCell> BiomeCells { get; private set; } public IList<BiomeCell> BiomeCells { get; private set; }
Perlin TempNoise = new Perlin(); Perlin TempNoise, RainNoise;
Perlin RainNoise = new Perlin();
public BiomeMap(int seed) public BiomeMap(int seed)
{ {
TempNoise = new Perlin(seed);
RainNoise = new Perlin(seed);
BiomeCells = new List<BiomeCell>(); BiomeCells = new List<BiomeCell>();
TempNoise.Persistance = 1.45; TempNoise.Persistance = 1.45;
TempNoise.Frequency = 0.015; TempNoise.Frequency = 0.015;

View File

@ -16,7 +16,16 @@ namespace TrueCraft.Core.World
public static readonly int Height = 128; public static readonly int Height = 128;
public string Name { get; set; } public string Name { get; set; }
public int Seed { get; set; } private int _Seed;
public int Seed
{
get { return _Seed; }
set
{
_Seed = value;
BiomeDiagram = new BiomeMap(_Seed);
}
}
private Coordinates3D? _SpawnPoint; private Coordinates3D? _SpawnPoint;
public Coordinates3D SpawnPoint public Coordinates3D SpawnPoint
{ {
@ -63,19 +72,18 @@ namespace TrueCraft.Core.World
public World(string name) : this() public World(string name) : this()
{ {
Name = name; Name = name;
Seed = new Random().Next(); Seed = MathHelper.Random.Next();
BiomeDiagram = new BiomeMap(Seed);
} }
public World(string name, IChunkProvider chunkProvider) : this(name) public World(string name, IChunkProvider chunkProvider) : this(name)
{ {
ChunkProvider = chunkProvider; ChunkProvider = chunkProvider;
ChunkProvider.Initialize(this);
} }
public World(string name, int seed, IChunkProvider chunkProvider) : this(name, chunkProvider) public World(string name, int seed, IChunkProvider chunkProvider) : this(name, chunkProvider)
{ {
Seed = seed; Seed = seed;
BiomeDiagram = new BiomeMap(Seed);
} }
public static World LoadWorld(string baseDirectory) public static World LoadWorld(string baseDirectory)
@ -94,7 +102,8 @@ namespace TrueCraft.Core.World
file.RootTag["SpawnPoint"]["Z"].IntValue); file.RootTag["SpawnPoint"]["Z"].IntValue);
world.Seed = file.RootTag["Seed"].IntValue; world.Seed = file.RootTag["Seed"].IntValue;
var providerName = file.RootTag["ChunkProvider"].StringValue; var providerName = file.RootTag["ChunkProvider"].StringValue;
var provider = (IChunkProvider)Activator.CreateInstance(Type.GetType(providerName), world); var provider = (IChunkProvider)Activator.CreateInstance(Type.GetType(providerName));
provider.Initialize(world);
if (file.RootTag.Contains("Name")) if (file.RootTag.Contains("Name"))
world.Name = file.RootTag["Name"].StringValue; world.Name = file.RootTag["Name"].StringValue;
world.ChunkProvider = provider; world.ChunkProvider = provider;