diff --git a/.cargo/config b/.cargo/config index fd1601755c..7950c8616b 100644 --- a/.cargo/config +++ b/.cargo/config @@ -6,8 +6,9 @@ rustflags = [ [alias] generate = "run --package tools --" test-server = "-Zpackage-features run --bin veloren-server-cli --no-default-features" -tracy-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --no-default-features --features tracy --profile dev" -test-voxygen = "-Zpackage-features run --bin veloren-voxygen --no-default-features --features gl" -tracy-voxygen = "-Zunstable-options -Zpackage-features run --bin veloren-voxygen --no-default-features --features tracy,gl --profile dev" +tracy-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --no-default-features --features tracy --profile no_overflow" +tracy-server-world = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --features tracy --profile no_overflow" +test-voxygen = "-Zpackage-features run --bin veloren-voxygen --no-default-features --features gl,simd" +tracy-voxygen = "-Zunstable-options -Zpackage-features run --bin veloren-voxygen --no-default-features --features tracy,gl,simd --profile no_overflow" server = "run --bin veloren-server-cli" diff --git a/common/src/cmd.rs b/common/src/cmd.rs index adf77aa169..a8ca3e01e0 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -42,6 +42,7 @@ pub enum ChatCommand { Campfire, Debug, DebugColumn, + DebugChunk, Dummy, Explosion, Faction, @@ -90,6 +91,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[ ChatCommand::Campfire, ChatCommand::Debug, ChatCommand::DebugColumn, + ChatCommand::DebugChunk, ChatCommand::Dummy, ChatCommand::Explosion, ChatCommand::Faction, @@ -221,6 +223,11 @@ impl ChatCommand { "Prints some debug information about a column", NoAdmin, ), + ChatCommand::DebugChunk => cmd( + vec![], + "Prints some debug information about the current chunk", + NoAdmin, + ), ChatCommand::Dummy => cmd(vec![], "Spawns a training dummy", Admin), ChatCommand::Explosion => cmd( vec![Float("radius", 5.0, Required)], @@ -420,6 +427,7 @@ impl ChatCommand { ChatCommand::Campfire => "campfire", ChatCommand::Debug => "debug", ChatCommand::DebugColumn => "debug_column", + ChatCommand::DebugChunk => "debug_chunk", ChatCommand::Dummy => "dummy", ChatCommand::Explosion => "explosion", ChatCommand::Faction => "faction", diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 7ea9da3e64..80f3e6c8f2 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -74,6 +74,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler { ChatCommand::Campfire => handle_spawn_campfire, ChatCommand::Debug => handle_debug, ChatCommand::DebugColumn => handle_debug_column, + ChatCommand::DebugChunk => handle_debug_chunk, ChatCommand::Dummy => handle_spawn_training_dummy, ChatCommand::Explosion => handle_explosion, ChatCommand::Faction => handle_faction, @@ -1628,6 +1629,28 @@ spawn_rate {:?} "#, } } +fn handle_debug_chunk( + server: &mut Server, + client: EcsEntity, + target: EcsEntity, + _args: String, + _action: &ChatCommand, +) { + if let Some(comp::Pos(current_pos)) = server.state.read_component_copied(target) { + let chunk_key = server.state.terrain().pos_key(current_pos.as_()); + let message = format!( + "The current chunk has these chunk coordinates: ({}, {})", + chunk_key.x, chunk_key.y + ); + server.notify_client(client, ChatType::CommandInfo.server_msg(message)); + } else { + server.notify_client( + client, + ChatType::CommandError.server_msg("You have no position."), + ); + } +} + fn find_target( ecs: &specs::World, opt_alias: Option, diff --git a/world/Cargo.toml b/world/Cargo.toml index a666fcf2db..8e27e90a02 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -35,3 +35,8 @@ ron = { version = "0.6", default-features = false } criterion = "0.3" tracing-subscriber = { version = "0.2.3", default-features = false, features = ["fmt", "chrono", "ansi", "smallvec"] } minifb = "0.14.0" + +[[bench]] +harness = false +name = "chunk_gen" + diff --git a/world/benches/chunk_gen.rs b/world/benches/chunk_gen.rs new file mode 100644 index 0000000000..4c56a76226 --- /dev/null +++ b/world/benches/chunk_gen.rs @@ -0,0 +1,41 @@ +use criterion::{black_box, criterion_group, criterion_main, Benchmark, Criterion}; +use vek::*; +use veloren_world::{sim, World}; + +// 136 chunks total +const MIN_CHUNK: Vec2 = Vec2 { x: 382, y: 406 }; +const MAX_CHUNK: Vec2 = Vec2 { x: 398, y: 413 }; + +pub fn criterion_benchmark(c: &mut Criterion) { + // Setup world + let (world, index) = World::generate(42, sim::WorldOpts { + // NOTE: If this gets too expensive, we can turn it off. + // TODO: Consider an option to turn off all erosion as well, or even provide altitude + // directly with a closure. + seed_elements: true, + world_file: sim::FileOpts::LoadAsset(sim::DEFAULT_WORLD_MAP.into()), + ..Default::default() + }); + //let index = Box::leak(Box::new(index)).as_index_ref(); + let to_gen = (MIN_CHUNK.x..MAX_CHUNK.x + 1) + .flat_map(|x| (MIN_CHUNK.y..MAX_CHUNK.y + 1).map(move |y| Vec2::new(x, y))) + .collect::>(); + + c.bench( + "chunk_generation", + Benchmark::new("generating area of forest chunks", move |b| { + let index = index.as_index_ref(); + b.iter(|| { + black_box(&to_gen) + .iter() + .map(|pos| (pos, world.generate_chunk(index, *pos, || false).unwrap())) + .collect::>() + }) + }) + // Lower sample size to save time + .sample_size(15), + ); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/world/src/lib.rs b/world/src/lib.rs index 7aa02fb46c..7beed18d43 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -39,6 +39,7 @@ use common::{ comp::{self, bird_medium, quadruped_low, quadruped_medium, quadruped_small}, generation::{ChunkSupplement, EntityInfo}, msg::WorldMapMsg, + span, terrain::{Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize}, vol::{ReadVol, RectVolSize, WriteVol}, }; @@ -106,6 +107,7 @@ impl World { // TODO: misleading name mut should_continue: impl FnMut() -> bool, ) -> Result<(TerrainChunk, ChunkSupplement), ()> { + span!(_guard, "generate_chunk", "World::generate_chunk"); let mut sampler = self.sample_blocks(); let chunk_wpos2d = chunk_pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);