mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixes to worldgen and adding a debug command.
Humidity and temperature are now indexed to uniform altitude *over land chunks* (and water chunks adjacent to land) rather than over the whole range of altitude. This is necessary in order to satisfy the uniformity conditions of the formula for weighted sum CDF. Additionally, fixes the computation of whether a tree should be generated or not. Previously, it was using a source of randomness scaled to use much less than the full 0-1 range; this has been resolved. This makes for much nicer and more gradual transitions between densities and reduces the amount of completely barren landscapes, while also making forests larger. Finally, this commit adds a server command, debug_column, which returns some useful debug information about a column given an x and y coordinate. This is useful for debugging worldgen.
This commit is contained in:
parent
61546239a8
commit
c02f2a7f9e
@ -172,7 +172,8 @@ impl Client {
|
||||
pub fn set_view_distance(&mut self, view_distance: u32) {
|
||||
self.view_distance = Some(view_distance.max(1).min(25));
|
||||
self.postbox
|
||||
.send_message(ClientMsg::SetViewDistance(self.view_distance.unwrap())); // Can't fail
|
||||
.send_message(ClientMsg::SetViewDistance(self.view_distance.unwrap()));
|
||||
// Can't fail
|
||||
}
|
||||
|
||||
pub fn swap_inventory_slots(&mut self, a: usize, b: usize) {
|
||||
|
@ -10,6 +10,8 @@ use common::{
|
||||
msg::ServerMsg,
|
||||
npc::{get_npc_name, NpcKind},
|
||||
state::TimeOfDay,
|
||||
terrain::TerrainChunkSize,
|
||||
vol::VolSize,
|
||||
};
|
||||
use rand::Rng;
|
||||
use specs::{Builder, Entity as EcsEntity, Join};
|
||||
@ -198,7 +200,14 @@ lazy_static! {
|
||||
"/adminify <playername> : Temporarily gives a player admin permissions or removes them",
|
||||
true,
|
||||
handle_adminify,
|
||||
)
|
||||
),
|
||||
ChatCommand::new(
|
||||
"debug_column",
|
||||
"{} {}",
|
||||
"/debug_column <x> <y> : Prints some debug information about a column",
|
||||
false,
|
||||
handle_debug_column,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@ -828,3 +837,50 @@ fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
||||
.notify(entity, ServerMsg::private(String::from(action.help_string)));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_debug_column(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
||||
let sim = server.world.sim();
|
||||
if let Ok((x, y)) = scan_fmt!(&args, action.arg_fmt, i32, i32) {
|
||||
let wpos = Vec2::new(x, y);
|
||||
/* let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||
e / sz as i32
|
||||
}); */
|
||||
|
||||
let foo = || {
|
||||
// let sim_chunk = sim.get(chunk_pos)?;
|
||||
let alt_base = sim.get_interpolated(wpos, |chunk| chunk.alt_base)?;
|
||||
let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?;
|
||||
let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?;
|
||||
let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?;
|
||||
let humidity = sim.get_interpolated(wpos, |chunk| chunk.humidity)?;
|
||||
let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?;
|
||||
let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?;
|
||||
let spawn_rate = sim.get_interpolated(wpos, |chunk| chunk.spawn_rate)?;
|
||||
|
||||
Some(format!(
|
||||
r#"wpos: {:?}
|
||||
alt_base {:?}
|
||||
alt {:?}
|
||||
chaos {:?}
|
||||
temp {:?}
|
||||
humidity {:?}
|
||||
rockiness {:?}
|
||||
tree_density {:?}
|
||||
spawn_rate {:?} "#,
|
||||
wpos, alt_base, alt, chaos, temp, humidity, rockiness, tree_density, spawn_rate
|
||||
))
|
||||
};
|
||||
if let Some(s) = foo() {
|
||||
server.clients.notify(entity, ServerMsg::private(s));
|
||||
} else {
|
||||
server.clients.notify(
|
||||
entity,
|
||||
ServerMsg::private(String::from("Not a pregenerated chunk.")),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
server
|
||||
.clients
|
||||
.notify(entity, ServerMsg::private(String::from(action.help_string)));
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
use common::{assets, terrain::Structure};
|
||||
use lazy_static::lazy_static;
|
||||
use std::sync::Arc;
|
||||
use std::u32;
|
||||
use vek::*;
|
||||
|
||||
static VOLUME_RAND: RandomPerm = RandomPerm::new(0xDB21C052);
|
||||
@ -25,7 +26,8 @@ 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.5
|
||||
let random_seed = (st_seed as f64) / (u32::MAX as f64);
|
||||
if (st_sample.tree_density as f64) < random_seed
|
||||
|| st_sample.alt < st_sample.water_level
|
||||
|| st_sample.spawn_rate < 0.5
|
||||
{
|
||||
|
@ -78,8 +78,8 @@ impl<'a> ColumnGen<'a> {
|
||||
|
||||
if seed % 5 == 2
|
||||
&& chunk.temp > CONFIG.desert_temp
|
||||
&& chunk.humidity < CONFIG.desert_hum
|
||||
&& chunk.alt > CONFIG.sea_level + 5.0
|
||||
&& chunk.chaos <= 0.35
|
||||
{
|
||||
Some(StructureData {
|
||||
pos,
|
||||
|
@ -55,6 +55,7 @@ struct GenCdf {
|
||||
alt_base: InverseCdf,
|
||||
chaos: InverseCdf,
|
||||
alt: InverseCdf,
|
||||
alt_no_seawater: InverseCdf,
|
||||
}
|
||||
|
||||
pub(crate) struct GenCtx {
|
||||
@ -223,8 +224,8 @@ impl WorldSim {
|
||||
// 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) {
|
||||
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 {
|
||||
@ -236,12 +237,21 @@ impl WorldSim {
|
||||
true
|
||||
};
|
||||
|
||||
// A version of alt that is uniform over *non-seawater* (or land-adjacent seawater) chunks.
|
||||
let alt_no_seawater = uniform_noise(|posi, wposf| {
|
||||
if pure_water(posi) {
|
||||
None
|
||||
} else {
|
||||
Some(alt[posi].1)
|
||||
}
|
||||
});
|
||||
|
||||
// -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))
|
||||
Some(gen_ctx.temp_nz.get((wposf.div(12000.0)).into_array()) as f32)
|
||||
}
|
||||
});
|
||||
|
||||
@ -265,6 +275,7 @@ impl WorldSim {
|
||||
alt_base,
|
||||
chaos,
|
||||
alt,
|
||||
alt_no_seawater,
|
||||
};
|
||||
|
||||
let mut chunks = Vec::new();
|
||||
@ -530,7 +541,8 @@ impl SimChunk {
|
||||
let map_edge_factor = map_edge_factor(posi);
|
||||
let (_, chaos) = gen_cdf.chaos[posi];
|
||||
let (humid_uniform, _) = gen_cdf.humid_base[posi];
|
||||
let (alt_uniform, alt_pre) = gen_cdf.alt[posi];
|
||||
let (_, alt_pre) = gen_cdf.alt[posi];
|
||||
let (alt_uniform, _) = gen_cdf.alt_no_seawater[posi];
|
||||
let (temp_uniform, _) = gen_cdf.temp_base[posi];
|
||||
|
||||
// Take the weighted average of our randomly generated base humidity, the scaled
|
||||
|
Loading…
Reference in New Issue
Block a user