diff --git a/server/src/lib.rs b/server/src/lib.rs index 5b16e6d0ec..f5006897c3 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -89,7 +89,7 @@ impl Server { let mut state = State::default(); state .ecs_mut() - .add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 380.0))); + .add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 512.0))); state.ecs_mut().add_resource(EventBus::default()); // Set starting time for the server. diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index c02a1385b9..0585e3528c 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -7,7 +7,7 @@ pub use self::settlement::Settlement; use crate::{ all::ForestKind, - util::{Sampler, StructureGen2d}, + util::{seed_expan, Sampler, StructureGen2d}, CONFIG, }; use common::{ @@ -54,32 +54,37 @@ pub struct WorldSim { } impl WorldSim { - pub fn generate(seed: u32) -> Self { + pub fn generate(mut seed: u32) -> Self { + let mut gen_seed = || { + seed = seed_expan::diffuse(seed + 1); + seed + }; + let mut gen_ctx = GenCtx { - turb_x_nz: SuperSimplex::new().set_seed(seed + 0), - turb_y_nz: SuperSimplex::new().set_seed(seed + 1), - chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(seed + 2), - hill_nz: SuperSimplex::new().set_seed(seed + 3), + turb_x_nz: SuperSimplex::new().set_seed(gen_seed()), + turb_y_nz: SuperSimplex::new().set_seed(gen_seed()), + chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(gen_seed()), + hill_nz: SuperSimplex::new().set_seed(gen_seed()), alt_nz: HybridMulti::new() .set_octaves(8) .set_persistence(0.1) - .set_seed(seed + 4), - temp_nz: SuperSimplex::new().set_seed(seed + 5), - dry_nz: BasicMulti::new().set_seed(seed + 6), - small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 7), - rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 8), - cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 9), - warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 10), + .set_seed(gen_seed()), + temp_nz: SuperSimplex::new().set_seed(gen_seed()), + dry_nz: BasicMulti::new().set_seed(gen_seed()), + small_nz: BasicMulti::new().set_octaves(2).set_seed(gen_seed()), + rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(gen_seed()), + cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(gen_seed()), + warp_nz: BasicMulti::new().set_octaves(3).set_seed(gen_seed()), tree_nz: BasicMulti::new() .set_octaves(12) .set_persistence(0.75) - .set_seed(seed + 12), - cave_0_nz: SuperSimplex::new().set_seed(seed + 13), - cave_1_nz: SuperSimplex::new().set_seed(seed + 14), + .set_seed(gen_seed()), + cave_0_nz: SuperSimplex::new().set_seed(gen_seed()), + cave_1_nz: SuperSimplex::new().set_seed(gen_seed()), - structure_gen: StructureGen2d::new(seed, 32, 24), - region_gen: StructureGen2d::new(seed + 1, 400, 96), - cliff_gen: StructureGen2d::new(seed + 2, 80, 56), + structure_gen: StructureGen2d::new(gen_seed(), 32, 24), + region_gen: StructureGen2d::new(gen_seed(), 400, 96), + cliff_gen: StructureGen2d::new(gen_seed(), 80, 56), }; let mut chunks = Vec::new(); @@ -94,40 +99,7 @@ impl WorldSim { chunks, locations: Vec::new(), gen_ctx, - rng: ChaChaRng::from_seed([ - (seed >> 0) as u8, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - (seed >> 8) as u8, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - (seed >> 16) as u8, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - (seed >> 24) as u8, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]), + rng: ChaChaRng::from_seed(seed_expan::rng_state(seed)), }; this.seed_elements(); diff --git a/world/src/util/mod.rs b/world/src/util/mod.rs index a8a71d0c03..f0a44c87c8 100644 --- a/world/src/util/mod.rs +++ b/world/src/util/mod.rs @@ -1,6 +1,7 @@ pub mod hash_cache; pub mod random; pub mod sampler; +pub mod seed_expan; pub mod structure; pub mod unit_chooser; diff --git a/world/src/util/seed_expan.rs b/world/src/util/seed_expan.rs new file mode 100644 index 0000000000..899c2d435e --- /dev/null +++ b/world/src/util/seed_expan.rs @@ -0,0 +1,20 @@ +/// Simple non-cryptographic diffusion function. +pub fn diffuse(mut x: u32) -> u32 { + x = x.wrapping_add(0x7ed55d16).wrapping_add(x << 12); + x = (x ^ 0xc761c23c) ^ (x >> 19); + x = x.wrapping_add(0x165667b1).wrapping_add(x << 5); + x = x.wrapping_add(0xd3a2646c) ^ (x << 9); + x = x.wrapping_add(0xfd7046c5).wrapping_add(x << 3); + x = (x ^ 0xb55a4f09) ^ (x >> 16); + x +} + +/// Expand a 32 bit seed into a 32 byte RNG state. +pub fn rng_state(mut x: u32) -> [u8; 32] { + let mut r: [u32; 8] = [0; 8]; + for s in &mut r { + x = diffuse(x); + *s = x; + } + unsafe { std::mem::transmute(r) } +}