Improved worldgen seed expansion

This commit is contained in:
Acrimon 2019-08-05 18:46:28 +02:00
parent d5aee13c91
commit 393ac4610c
3 changed files with 97 additions and 52 deletions

View File

@ -7,7 +7,7 @@ pub use self::settlement::Settlement;
use crate::{
all::ForestKind,
util::{Sampler, StructureGen2d},
util::{seed_expan, Sampler, StructureGen2d},
CONFIG,
};
use common::{
@ -55,31 +55,32 @@ pub struct WorldSim {
impl WorldSim {
pub fn generate(seed: u32) -> Self {
let seeds = seed_expan::diffused_field(seed, 17);
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(seeds[0]),
turb_y_nz: SuperSimplex::new().set_seed(seeds[1]),
chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(seeds[2]),
hill_nz: SuperSimplex::new().set_seed(seeds[3]),
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(seeds[4]),
temp_nz: SuperSimplex::new().set_seed(seeds[5]),
dry_nz: BasicMulti::new().set_seed(seeds[6]),
small_nz: BasicMulti::new().set_octaves(2).set_seed(seeds[7]),
rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seeds[8]),
cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seeds[9]),
warp_nz: BasicMulti::new().set_octaves(3).set_seed(seeds[10]),
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(seeds[11]),
cave_0_nz: SuperSimplex::new().set_seed(seeds[12]),
cave_1_nz: SuperSimplex::new().set_seed(seeds[13]),
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(seeds[14], 32, 24),
region_gen: StructureGen2d::new(seeds[15], 400, 96),
cliff_gen: StructureGen2d::new(seeds[17], 80, 56),
};
let mut chunks = Vec::new();
@ -94,40 +95,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::expand_seed_to_rng(seed)),
};
this.seed_elements();

View File

@ -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;

View File

@ -0,0 +1,76 @@
static SBOX: [u8; 256] = [
206, 21, 212, 69, 54, 234, 13, 42, 184, 48, 92, 64, 196, 55, 225, 235, 229, 120, 135, 72, 32,
147, 74, 142, 197, 79, 139, 164, 110, 57, 176, 47, 192, 174, 178, 49, 193, 71, 78, 18, 237, 81,
255, 187, 5, 246, 247, 109, 26, 44, 93, 230, 96, 102, 204, 31, 100, 175, 182, 245, 9, 0, 127,
161, 125, 52, 129, 179, 209, 130, 219, 77, 218, 252, 61, 75, 62, 248, 124, 220, 98, 87, 63,
163, 101, 40, 29, 4, 36, 123, 23, 238, 134, 35, 17, 169, 226, 19, 2, 253, 158, 172, 37, 104,
183, 194, 43, 167, 59, 215, 162, 88, 140, 25, 133, 221, 132, 159, 232, 250, 154, 10, 211, 112,
146, 189, 141, 95, 1, 111, 28, 160, 73, 181, 67, 30, 190, 157, 148, 149, 11, 8, 41, 217, 106,
39, 214, 152, 180, 168, 14, 56, 70, 34, 137, 243, 45, 195, 94, 38, 7, 116, 16, 136, 82, 114,
186, 105, 15, 223, 200, 131, 85, 20, 128, 210, 97, 233, 151, 241, 138, 6, 60, 24, 249, 12, 207,
239, 171, 65, 113, 115, 22, 107, 68, 143, 90, 119, 185, 153, 166, 46, 155, 191, 254, 58, 150,
251, 99, 213, 118, 240, 122, 108, 231, 126, 177, 80, 227, 91, 145, 203, 228, 198, 236, 53, 50,
51, 76, 242, 103, 117, 170, 173, 121, 188, 27, 244, 205, 224, 144, 3, 89, 84, 66, 202, 83, 156,
216, 33, 165, 86, 222, 199, 208, 201,
];
fn sbox(x: u64) -> u64 {
let mut bytes = x.to_ne_bytes();
for byte in &mut bytes {
*byte = SBOX[*byte as usize];
}
u64::from_ne_bytes(bytes)
}
// chaotic bijective function
fn diffuse_rnd(mut x: u64) -> u64 {
x = x.wrapping_mul(0x6eed0e9da4d94a4f);
let a = x >> 32;
let b = x >> 60;
x ^= a >> b;
x = x.wrapping_mul(0x6eed0e9da4d94a4f);
sbox(x)
}
fn diffuse(mut x: u64) -> u64 {
for _ in 0..4 {
x = diffuse_rnd(x);
}
x
}
fn initial_expand(x: u32) -> u64 {
(x as u64).wrapping_mul(0x2f72b4215a3d8caf).pow(2)
}
fn truncate(x: u64) -> u32 {
let xb = x.to_ne_bytes();
let nb = [
xb[0].wrapping_mul(xb[1]),
xb[2].wrapping_mul(xb[3]),
xb[4].wrapping_mul(xb[5]),
xb[6].wrapping_mul(xb[7]),
];
u32::from_ne_bytes(nb)
}
pub fn diffused_field(seed: u32, amount: u32) -> Vec<u32> {
let mut field = Vec::new();
for i in 0..amount {
let n = truncate(diffuse(initial_expand(seed + i)));
field.push(n);
}
field
}
pub fn expand_seed_to_rng(seed: u32) -> [u8; 32] {
let mut r: [u64; 4] = [0; 4];
let mut state: u64 = initial_expand(seed);
for i in 0..4 {
state = diffuse(state);
r[i] = state;
}
unsafe { std::mem::transmute(r) }
}