Chaos doesn't depend on temperature anymore.

Also fix some things to use a consistent coordinate system and bump up
tree density and variation around tree density in hopes of creating more
aesthetically pleasing jungles.  However, this does change worldgen a
bit, so please make sure you look through it before merging.
This commit is contained in:
Joshua Yanovski 2019-08-25 17:49:33 +02:00
parent 47380090fa
commit 6f12a240de
3 changed files with 45 additions and 27 deletions

View File

@ -25,7 +25,7 @@ pub fn structure_gen<'a>(
let st_sample = &structure_samples[idx].as_ref()?;
// Assuming it's a tree... figure out when it SHOULDN'T spawn
if st_sample.tree_density < 0.5 + (st_seed as f32 / 1000.0).fract() * 0.2
if st_sample.tree_density < 0.5 + (st_seed as f32 / 1000.0).fract() * 0.5
|| st_sample.alt < st_sample.water_level
|| st_sample.spawn_rate < 0.5
{

View File

@ -5,7 +5,10 @@ mod util;
// Reexports
pub use self::location::Location;
pub use self::settlement::Settlement;
use self::util::{cdf_irwin_hall, uniform_idx_as_vec2, uniform_noise, InverseCdf};
use self::util::{
cdf_irwin_hall, uniform_idx_as_vec2, uniform_noise, vec2_as_uniform_idx,
InverseCdf,
};
use crate::{
all::ForestKind,
@ -143,11 +146,6 @@ impl WorldSim {
)
});
// -1 to 1.
let temp_base = uniform_noise(|_, wposf| {
Some((gen_ctx.temp_nz.get((wposf.div(12000.0)).into_array()) as f32))
});
// chaos produces a value in [0.1, 1.24]. It is a meta-level factor intended to reflect how
// "chaotic" the region is--how much weird stuff is going on on this terrain.
let chaos = uniform_noise(|posi, wposf| {
@ -180,20 +178,6 @@ impl WorldSim {
// hill is 0 about 50% of the time).
// [0, 1] + 0.15 * [0, 1.6] = [0, 1.24]
.add(0.2 * hill)
// [0, 1.24] * [0.35, 1.0] = [0, 1.24].
// Sharply decreases (towards 0.35) when temperature is near desert_temp (from below),
// then saturates just before it actually becomes desert. Otherwise stays at 1.
// Note that this is not the *final* temperature, only the initial noise value for
// temperature.
.mul(
temp_base[posi]
.1
.sub(0.45)
.neg()
.mul(12.0)
.max(0.35)
.min(1.0),
)
// We can't have *no* chaos!
.max(0.1),
)
@ -236,9 +220,36 @@ impl WorldSim {
Some((alt_base[posi].1 + alt_main.mul(chaos[posi].1)).mul(map_edge_factor(posi)))
});
// Check whether any tiles around this tile are not water (since Lerp will ensure that they
// are included).
let pure_water = |posi| {
let pos = uniform_idx_as_vec2(posi);
for x in (pos.x - 1..=pos.x + 1) {
for y in (pos.y - 1..=pos.y + 1) {
if x >= 0 && y >= 0 && x < WORLD_SIZE.x as i32 && y < WORLD_SIZE.y as i32 {
let posi = vec2_as_uniform_idx(Vec2::new(x, y));
if alt[posi].1.mul(CONFIG.mountain_scale) > 0.0 {
return false
}
}
}
}
true
};
// -1 to 1.
let temp_base = uniform_noise(|posi, wposf| {
if pure_water(posi) {
None
} else {
Some((gen_ctx.temp_nz.get((wposf.div(12000.0)).into_array()) as f32))
}
});
// 0 to 1, hopefully.
let humid_base = uniform_noise(|posi, wposf| {
if alt[posi].1 <= 5.0.div(CONFIG.mountain_scale) {
// Check whether any tiles around this tile are water.
if pure_water(posi) {
None
} else {
Some(
@ -398,7 +409,7 @@ impl WorldSim {
.map2(WORLD_SIZE, |e, sz| e >= 0 && e < sz as i32)
.reduce_and()
{
Some(&self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize])
Some(&self.chunks[vec2_as_uniform_idx(chunk_pos)])
} else {
None
}
@ -409,7 +420,7 @@ impl WorldSim {
.map2(WORLD_SIZE, |e, sz| e >= 0 && e < sz as i32)
.reduce_and()
{
Some(&mut self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize])
Some(&mut self.chunks[vec2_as_uniform_idx(chunk_pos)])
} else {
None
}
@ -573,9 +584,9 @@ impl SimChunk {
// Weighted logit sum.
logistic_cdf(logit(humidity) + 0.5 * logit(tree_density))
}
// rescale to (-0.9, 0.9)
// rescale to (-0.95, 0.95)
.sub(0.5)
.mul(0.9)
.mul(0.95)
.add(0.5)
};
@ -614,6 +625,7 @@ impl SimChunk {
}
} else if temp > CONFIG.tropical_temp {
if humidity > CONFIG.jungle_hum {
println!("Mangrove: {:?}", wposf);
ForestKind::Mangrove
} else if humidity > CONFIG.forest_hum {
// NOTE: Probably the wrong kind of tree for this climate.

View File

@ -96,7 +96,13 @@ pub type InverseCdf = Box<[(f32, f32)]>;
/// Computes the position Vec2 of a SimChunk from an index, where the index was generated by
/// uniform_noise.
pub fn uniform_idx_as_vec2(idx: usize) -> Vec2<i32> {
Vec2::new((idx / WORLD_SIZE.x) as i32, (idx % WORLD_SIZE.x) as i32)
Vec2::new((idx % WORLD_SIZE.x) as i32, (idx / WORLD_SIZE.x) as i32)
}
/// Computes the index of a Vec2 of a SimChunk from a position, where the index is generated by
/// uniform_noise. NOTE: Both components of idx should be in-bounds!
pub fn vec2_as_uniform_idx(idx: Vec2<i32>) -> usize {
(idx.y as usize * WORLD_SIZE.x + idx.x as usize) as usize
}
/// Compute inverse cumulative distribution function for arbitrary function f, the hard way. We