From 87a7d7afd17c87788d6c0fd722b77fae8ce14210 Mon Sep 17 00:00:00 2001
From: Imbris <imbrisf@gmail.com>
Date: Sat, 13 Mar 2021 01:48:30 -0500
Subject: [PATCH 1/3] Move server-cli commands to separate file, tracy
 profiling par_join improvements, misc improvements - remove overwritten
 logging setting in server-cli - add server-cli command to load a random area
 for testing without a client - make admin add/remove commands modify ingame
 players instead of needing to reconnect - add spans to par_join jobs - added
 test command that loads up an area of the world - add tracy-world-server
 alias - set debug directives to info for logging

---
 .cargo/config                |   1 +
 common/base/src/lib.rs       |  19 +++++
 common/ecs/src/system.rs     |   5 +-
 common/src/lib.rs            |   5 ++
 common/src/terrain/mod.rs    |  21 ++++++
 common/sys/src/phys.rs       |  46 +++++++++---
 server-cli/src/admin.rs      |   4 +-
 server-cli/src/cmd.rs        | 140 +++++++++++++++++++++++++++++++++++
 server-cli/src/logging.rs    |  11 +--
 server-cli/src/main.rs       |  11 ++-
 server-cli/src/tui_runner.rs | 129 +-------------------------------
 server/src/lib.rs            |  93 ++++++++++++++++-------
 server/src/state_ext.rs      |  56 ++++++++++++++
 server/src/sys/agent.rs      |  10 ++-
 voxygen/src/logging.rs       |   4 +-
 15 files changed, 374 insertions(+), 181 deletions(-)
 create mode 100644 server-cli/src/cmd.rs

diff --git a/.cargo/config b/.cargo/config
index 09fa64d2ea..f1923f273e 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -8,6 +8,7 @@ csv-export = "run --manifest-path common/Cargo.toml --features=bin_csv --bin csv
 csv-import = "run --manifest-path common/Cargo.toml --features=bin_csv --bin csv_import"
 test-server = "-Zpackage-features run --bin veloren-server-cli --no-default-features -- -b"
 tracy-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --no-default-features --features tracy,simd --profile no_overflow"
+tracy-world-server = "-Zunstable-options -Zpackage-features run --bin veloren-server-cli --features tracy,simd --profile no_overflow -- -bi"
 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/base/src/lib.rs b/common/base/src/lib.rs
index e08ac271ec..c1e1704880 100644
--- a/common/base/src/lib.rs
+++ b/common/base/src/lib.rs
@@ -41,6 +41,25 @@ macro_rules! span {
     };
 }
 
+/// Like the span macro but only used when profiling and not in regular tracing
+/// operations
+#[macro_export]
+macro_rules! prof_span {
+    ($guard_name:tt, $name:expr) => {
+        #[cfg(feature = "tracy")]
+        let $guard_name = $crate::tracy_client::Span::new(
+            $name,
+            "",
+            module_path!(),
+            line!(),
+            // No callstack since this has significant overhead
+            0,
+        );
+        #[cfg(not(feature = "tracy"))]
+        let $guard_name = ();
+    };
+}
+
 /// There's no guard, but really this is actually the guard
 pub struct GuardlessSpan {
     span: tracing::Span,
diff --git a/common/ecs/src/system.rs b/common/ecs/src/system.rs
index f1459967f4..033ed7818d 100644
--- a/common/ecs/src/system.rs
+++ b/common/ecs/src/system.rs
@@ -253,7 +253,10 @@ where
     fn run(&mut self, data: Self::SystemData) {
         common_base::span!(_guard, "run", &format!("{}::Sys::run", T::NAME));
         self.cpu_stats.reset();
-        T::run(self, data.0);
+        {
+            common_base::span!(_guard, "run inner", &format!("{}::Sys::run inner", T::NAME));
+            T::run(self, data.0);
+        }
         self.cpu_stats.end();
         data.1
             .stats
diff --git a/common/src/lib.rs b/common/src/lib.rs
index cd1c62c9bd..3f7a5f35a9 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -18,6 +18,11 @@
     trait_alias,
     type_alias_impl_trait
 )]
+
+/// Re-exported crates
+pub use uuid;
+
+// modules
 #[cfg(not(target_arch = "wasm32"))]
 pub mod assets;
 #[cfg(not(target_arch = "wasm32"))] pub mod astar;
diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs
index e1a18f2dbc..b108d302c3 100644
--- a/common/src/terrain/mod.rs
+++ b/common/src/terrain/mod.rs
@@ -49,6 +49,27 @@ impl RectVolSize for TerrainChunkSize {
     };
 }
 
+impl TerrainChunkSize {
+    #[inline(always)]
+    /// Convert dimensions in terms of chunks into dimensions in terms of blocks
+    /// ```
+    /// assert_eq!(TerrainChunkSize::blocks(Vec2::new(3, 2)), Vec2::new(96, 64));
+    /// ```
+    pub fn blocks(chunks: Vec2<u32>) -> Vec2<u32> { chunks * Self::RECT_SIZE }
+
+    /// Calculate the world position (i.e. in blocks) at the center of this
+    /// chunk
+    /// ```
+    /// assert_eq!(
+    ///     TerrainChunkSize::center_wpos(Vec2::new(0, 2)),
+    ///     Vec2::new(16, 80)
+    /// );
+    /// ```
+    pub fn center_wpos(chunk_pos: Vec2<i32>) -> Vec2<i32> {
+        chunk_pos * Self::RECT_SIZE.as_::<i32>() + Self::RECT_SIZE.as_::<i32>() / 2
+    }
+}
+
 // TerrainChunkMeta
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs
index e58197ed09..cb0ee3cd51 100644
--- a/common/sys/src/phys.rs
+++ b/common/sys/src/phys.rs
@@ -10,7 +10,7 @@ use common::{
     uid::Uid,
     vol::ReadVol,
 };
-use common_base::span;
+use common_base::{prof_span, span};
 use common_ecs::{Job, Origin, ParMode, Phase, PhysicsMetrics, System};
 use rayon::iter::ParallelIterator;
 use specs::{Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
@@ -232,9 +232,12 @@ impl<'a> System<'a> for Sys {
                 sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground)
             })
             .map(|(e, p, v, vd, m, c, _, _, ph, pr, c_s)| (e, p, v, vd, m, c, ph, pr, c_s))
-            .fold(
-                PhysicsMetrics::default,
-                |mut metrics,
+            .map_init(
+                || {
+                    prof_span!(guard, "physics e<>e rayon job");
+                    guard
+                },
+                |_guard,
                  (
                     entity,
                     pos,
@@ -256,6 +259,9 @@ impl<'a> System<'a> for Sys {
 
                     let mut vel_delta = Vec3::zero();
 
+                    let mut entity_entity_collision_checks = 0;
+                    let mut entity_entity_collisions = 0;
+
                     for (
                         entity_other,
                         other,
@@ -307,7 +313,7 @@ impl<'a> System<'a> for Sys {
                             continue;
                         }
 
-                        metrics.entity_entity_collision_checks += 1;
+                        entity_entity_collision_checks += 1;
 
                         const MIN_COLLISION_DIST: f32 = 0.3;
                         let increments = ((previous_cache.velocity_dt
@@ -334,7 +340,7 @@ impl<'a> System<'a> for Sys {
                             {
                                 if !collided {
                                     physics.touch_entities.push(*other);
-                                    metrics.entity_entity_collisions += 1;
+                                    entity_entity_collisions += 1;
                                 }
 
                                 // Don't apply repulsive force to projectiles
@@ -353,7 +359,12 @@ impl<'a> System<'a> for Sys {
 
                     // Change velocity
                     vel.0 += vel_delta * dt.0;
-                    metrics
+
+                    // Metrics
+                    PhysicsMetrics {
+                        entity_entity_collision_checks,
+                        entity_entity_collisions,
+                    }
                 },
             )
             .reduce(PhysicsMetrics::default, |old, new| PhysicsMetrics {
@@ -380,13 +391,19 @@ impl<'a> System<'a> for Sys {
             !&mountings,
         )
         .par_join()
-        .fold(Vec::new, |
-            mut land_on_grounds,
+        .map_init(
+            || {
+                prof_span!(guard, "physics e<>t rayon job");
+                guard
+            },
+            |_guard,
             (entity, _scale, sticky, collider, mut pos, mut vel, _ori, mut physics_state, _),
         | {
+            let mut landed_on_ground = None;
+
             if sticky.is_some() && physics_state.on_surface().is_some() {
                 vel.0 = Vec3::zero();
-                return land_on_grounds;
+                return landed_on_ground;
             }
 
             // TODO: Use this
@@ -593,7 +610,7 @@ impl<'a> System<'a> for Sys {
                                 on_ground = true;
 
                                 if !was_on_ground {
-                                    land_on_grounds.push((entity, *vel));
+                                    landed_on_ground = Some((entity, *vel));
                                 }
                             } else if resolve_dir.z < 0.0 && vel.0.z >= 0.0 {
                                 on_ceiling = true;
@@ -770,7 +787,12 @@ impl<'a> System<'a> for Sys {
                 },
             }
 
-            land_on_grounds
+            landed_on_ground
+        }).fold(Vec::new, |mut lands_on_grounds, landed_on_ground| {
+            if let Some(land_on_ground) = landed_on_ground {
+                lands_on_grounds.push(land_on_ground);
+            }
+            lands_on_grounds
         }).reduce(Vec::new, |mut land_on_grounds_a, mut land_on_grounds_b| {
             land_on_grounds_a.append(&mut land_on_grounds_b);
             land_on_grounds_a
diff --git a/server-cli/src/admin.rs b/server-cli/src/admin.rs
index 281bc83ca8..9a9fef99cb 100644
--- a/server-cli/src/admin.rs
+++ b/server-cli/src/admin.rs
@@ -16,12 +16,12 @@ pub fn admin_subcommand(
     match sub_m.subcommand() {
         ("add", Some(sub_m)) => {
             if let Some(username) = sub_m.value_of("username") {
-                server::add_admin(username, &login_provider, editable_settings, data_dir)
+                server::add_admin(username, &login_provider, editable_settings, data_dir);
             }
         },
         ("remove", Some(sub_m)) => {
             if let Some(username) = sub_m.value_of("username") {
-                server::remove_admin(username, &login_provider, editable_settings, data_dir)
+                server::remove_admin(username, &login_provider, editable_settings, data_dir);
             }
         },
         // TODO: can clap enforce this?
diff --git a/server-cli/src/cmd.rs b/server-cli/src/cmd.rs
new file mode 100644
index 0000000000..953546b4e3
--- /dev/null
+++ b/server-cli/src/cmd.rs
@@ -0,0 +1,140 @@
+use core::time::Duration;
+use std::sync::mpsc::Sender;
+use tracing::{error, info, warn};
+
+#[derive(Debug, Clone)]
+pub enum Message {
+    AbortShutdown,
+    Shutdown { grace_period: Duration },
+    Quit,
+    AddAdmin(String),
+    RemoveAdmin(String),
+    LoadArea(u32),
+}
+
+struct Command<'a> {
+    name: &'a str,
+    description: &'a str,
+    // Whether or not the command splits the arguments on whitespace
+    split_spaces: bool,
+    args: usize,
+    cmd: fn(Vec<String>, &mut Sender<Message>),
+}
+
+// TODO: maybe we could be using clap here?
+const COMMANDS: [Command; 6] = [
+    Command {
+        name: "quit",
+        description: "Closes the server",
+        split_spaces: true,
+        args: 0,
+        cmd: |_, sender| sender.send(Message::Quit).unwrap(),
+    },
+    Command {
+        name: "shutdown",
+        description: "Initiates a graceful shutdown of the server, waiting the specified number \
+                      of seconds before shutting down",
+        split_spaces: true,
+        args: 1,
+        cmd: |args, sender| {
+            if let Ok(grace_period) = args.first().unwrap().parse::<u64>() {
+                sender
+                    .send(Message::Shutdown {
+                        grace_period: Duration::from_secs(grace_period),
+                    })
+                    .unwrap()
+            } else {
+                error!("Grace period must an integer")
+            }
+        },
+    },
+    Command {
+        name: "loadarea",
+        description: "Loads up the chunks in a random area and adds a entity that mimics a player \
+                      to keep them from despawning",
+        split_spaces: true,
+        args: 1,
+        cmd: |args, sender| {
+            if let Ok(view_distance) = args.first().unwrap().parse::<u32>() {
+                sender.send(Message::LoadArea(view_distance)).unwrap();
+            } else {
+                error!("View distance must be an integer");
+            }
+        },
+    },
+    Command {
+        name: "abortshutdown",
+        description: "Aborts a shutdown if one is in progress",
+        split_spaces: false,
+        args: 0,
+        cmd: |_, sender| sender.send(Message::AbortShutdown).unwrap(),
+    },
+    Command {
+        name: "admin",
+        description: "Add or remove an admin via \'admin add/remove <username>\'",
+        split_spaces: true,
+        args: 2,
+        cmd: |args, sender| match args.get(..2) {
+            Some([op, username]) if op == "add" => {
+                sender.send(Message::AddAdmin(username.clone())).unwrap()
+            },
+            Some([op, username]) if op == "remove" => {
+                sender.send(Message::RemoveAdmin(username.clone())).unwrap()
+            },
+            Some(_) => error!("First arg must be add or remove"),
+            _ => error!("Not enough args, should be unreachable"),
+        },
+    },
+    Command {
+        name: "help",
+        description: "List all command available",
+        split_spaces: true,
+        args: 0,
+        cmd: |_, _| {
+            info!("===== Help =====");
+            for command in COMMANDS.iter() {
+                info!("{} - {}", command.name, command.description)
+            }
+            info!("================");
+        },
+    },
+];
+
+pub fn parse_command(input: &str, msg_s: &mut Sender<Message>) {
+    let mut args = input.split_whitespace();
+
+    if let Some(cmd_name) = args.next() {
+        if let Some(cmd) = COMMANDS.iter().find(|cmd| cmd.name == cmd_name) {
+            let args = args.collect::<Vec<_>>();
+
+            let (arg_len, args) = if cmd.split_spaces {
+                (
+                    args.len(),
+                    args.into_iter()
+                        .map(|s| s.to_string())
+                        .collect::<Vec<String>>(),
+                )
+            } else {
+                (0, vec![args.into_iter().collect::<String>()])
+            };
+
+            use core::cmp::Ordering;
+            match arg_len.cmp(&cmd.args) {
+                Ordering::Less => error!("{} takes {} arguments", cmd_name, cmd.args),
+                Ordering::Greater => {
+                    warn!("{} only takes {} arguments", cmd_name, cmd.args);
+                    let cmd = cmd.cmd;
+
+                    cmd(args, msg_s)
+                },
+                Ordering::Equal => {
+                    let cmd = cmd.cmd;
+
+                    cmd(args, msg_s)
+                },
+            }
+        } else {
+            error!("{} not found", cmd_name);
+        }
+    }
+}
diff --git a/server-cli/src/logging.rs b/server-cli/src/logging.rs
index fb26085d0f..356e9938b2 100644
--- a/server-cli/src/logging.rs
+++ b/server-cli/src/logging.rs
@@ -1,6 +1,5 @@
 use crate::tuilog::TuiLog;
 use termcolor::{ColorChoice, StandardStream};
-use tracing::Level;
 use tracing_subscriber::{filter::LevelFilter, EnvFilter, FmtSubscriber};
 #[cfg(feature = "tracy")]
 use tracing_subscriber::{layer::SubscriberExt, prelude::*};
@@ -19,10 +18,10 @@ pub fn init(basic: bool) {
             .add_directive("hyper=info".parse().unwrap())
             .add_directive("prometheus_hyper=info".parse().unwrap())
             .add_directive("mio::pool=info".parse().unwrap())
-            .add_directive("mio::sys::windows=debug".parse().unwrap())
+            .add_directive("mio::sys::windows=info".parse().unwrap())
             .add_directive("h2=info".parse().unwrap())
             .add_directive("tokio_util=info".parse().unwrap())
-            .add_directive("rustls=debug".parse().unwrap())
+            .add_directive("rustls=info".parse().unwrap())
             .add_directive("veloren_network_protocol=info".parse().unwrap())
             .add_directive(
                 "veloren_server::persistence::character=info"
@@ -32,7 +31,6 @@ pub fn init(basic: bool) {
             .add_directive(LevelFilter::INFO.into())
     };
 
-    #[cfg(not(feature = "tracy"))]
     let filter = match std::env::var_os(RUST_LOG_ENV).map(|s| s.into_string()) {
         Some(Ok(env)) => {
             let mut filter = base_exceptions(EnvFilter::new(""));
@@ -49,6 +47,7 @@ pub fn init(basic: bool) {
 
     #[cfg(feature = "tracy")]
     tracing_subscriber::registry()
+        .with(filter)
         .with(tracing_tracy::TracyLayer::new().with_stackdepth(0))
         .init();
 
@@ -56,9 +55,7 @@ pub fn init(basic: bool) {
     // TODO: when tracing gets per Layer filters re-enable this when the tracy feature is being
     // used (and do the same in voxygen)
     {
-        let subscriber = FmtSubscriber::builder()
-            .with_max_level(Level::ERROR)
-            .with_env_filter(filter);
+        let subscriber = FmtSubscriber::builder().with_env_filter(filter);
 
         if basic {
             subscriber
diff --git a/server-cli/src/main.rs b/server-cli/src/main.rs
index fbd390fc36..550709a4d7 100644
--- a/server-cli/src/main.rs
+++ b/server-cli/src/main.rs
@@ -3,16 +3,16 @@
 #![feature(bool_to_option)]
 
 mod admin;
+/// `server-cli` interface commands not to be confused with the commands sent
+/// from the client to the server
+mod cmd;
 mod logging;
 mod settings;
 mod shutdown_coordinator;
 mod tui_runner;
 mod tuilog;
 
-use crate::{
-    shutdown_coordinator::ShutdownCoordinator,
-    tui_runner::{Message, Tui},
-};
+use crate::{cmd::Message, shutdown_coordinator::ShutdownCoordinator, tui_runner::Tui};
 use clap::{App, Arg, SubCommand};
 use common::clock::Clock;
 use common_base::span;
@@ -201,6 +201,9 @@ fn main() -> io::Result<()> {
                     Message::RemoveAdmin(username) => {
                         server.remove_admin(&username);
                     },
+                    Message::LoadArea(view_distance) => {
+                        server.create_centered_persister(view_distance);
+                    },
                 },
                 Err(mpsc::TryRecvError::Empty) | Err(mpsc::TryRecvError::Disconnected) => {},
             }
diff --git a/server-cli/src/tui_runner.rs b/server-cli/src/tui_runner.rs
index 136c2d94f2..e215496bb8 100644
--- a/server-cli/src/tui_runner.rs
+++ b/server-cli/src/tui_runner.rs
@@ -1,4 +1,4 @@
-use crate::logging::LOG;
+use crate::{cmd, logging::LOG, Message};
 use crossterm::{
     event::{DisableMouseCapture, EnableMouseCapture},
     execute,
@@ -12,7 +12,7 @@ use std::{
     },
     time::Duration,
 };
-use tracing::{debug, error, info, warn};
+use tracing::{debug, error, warn};
 use tui::{
     backend::CrosstermBackend,
     layout::Rect,
@@ -21,89 +21,6 @@ use tui::{
     Terminal,
 };
 
-#[derive(Debug, Clone)]
-pub enum Message {
-    AbortShutdown,
-    Shutdown { grace_period: Duration },
-    Quit,
-    AddAdmin(String),
-    RemoveAdmin(String),
-}
-
-pub struct Command<'a> {
-    pub name: &'a str,
-    pub description: &'a str,
-    // Whether or not the command splits the arguments on whitespace
-    pub split_spaces: bool,
-    pub args: usize,
-    pub cmd: fn(Vec<String>, &mut mpsc::Sender<Message>),
-}
-
-// TODO: mabye we could be using clap here?
-pub const COMMANDS: [Command; 5] = [
-    Command {
-        name: "quit",
-        description: "Closes the server",
-        split_spaces: true,
-        args: 0,
-        cmd: |_, sender| sender.send(Message::Quit).unwrap(),
-    },
-    Command {
-        name: "shutdown",
-        description: "Initiates a graceful shutdown of the server, waiting the specified number \
-                      of seconds before shutting down",
-        split_spaces: true,
-        args: 1,
-        cmd: |args, sender| {
-            if let Ok(grace_period) = args.first().unwrap().parse::<u64>() {
-                sender
-                    .send(Message::Shutdown {
-                        grace_period: Duration::from_secs(grace_period),
-                    })
-                    .unwrap()
-            } else {
-                error!("Grace period must an integer")
-            }
-        },
-    },
-    Command {
-        name: "abortshutdown",
-        description: "Aborts a shutdown if one is in progress",
-        split_spaces: false,
-        args: 0,
-        cmd: |_, sender| sender.send(Message::AbortShutdown).unwrap(),
-    },
-    Command {
-        name: "admin",
-        description: "Add or remove an admin via \'admin add/remove <username>\'",
-        split_spaces: true,
-        args: 2,
-        cmd: |args, sender| match args.get(..2) {
-            Some([op, username]) if op == "add" => {
-                sender.send(Message::AddAdmin(username.clone())).unwrap()
-            },
-            Some([op, username]) if op == "remove" => {
-                sender.send(Message::RemoveAdmin(username.clone())).unwrap()
-            },
-            Some(_) => error!("First arg must be add or remove"),
-            _ => error!("Not enough args, should be unreachable"),
-        },
-    },
-    Command {
-        name: "help",
-        description: "List all command available",
-        split_spaces: true,
-        args: 0,
-        cmd: |_, _| {
-            info!("===== Help =====");
-            for command in COMMANDS.iter() {
-                info!("{} - {}", command.name, command.description)
-            }
-            info!("================");
-        },
-    },
-];
-
 pub struct Tui {
     pub msg_r: mpsc::Receiver<Message>,
     background: Option<std::thread::JoinHandle<()>>,
@@ -129,7 +46,7 @@ impl Tui {
                 },
                 KeyCode::Enter => {
                     debug!(?input, "tui mode: command entered");
-                    parse_command(input, msg_s);
+                    cmd::parse_command(input, msg_s);
 
                     *input = String::new();
                 },
@@ -163,7 +80,7 @@ impl Tui {
                         },
                         Ok(_) => {
                             debug!(?line, "basic mode: command entered");
-                            parse_command(&line, &mut msg_s);
+                            crate::cmd::parse_command(&line, &mut msg_s);
                         },
                     }
                 }
@@ -263,41 +180,3 @@ impl Drop for Tui {
         Tui::shutdown(self.basic);
     }
 }
-
-fn parse_command(input: &str, msg_s: &mut mpsc::Sender<Message>) {
-    let mut args = input.split_whitespace();
-
-    if let Some(cmd_name) = args.next() {
-        if let Some(cmd) = COMMANDS.iter().find(|cmd| cmd.name == cmd_name) {
-            let args = args.collect::<Vec<_>>();
-
-            let (arg_len, args) = if cmd.split_spaces {
-                (
-                    args.len(),
-                    args.into_iter()
-                        .map(|s| s.to_string())
-                        .collect::<Vec<String>>(),
-                )
-            } else {
-                (0, vec![args.into_iter().collect::<String>()])
-            };
-
-            match arg_len.cmp(&cmd.args) {
-                std::cmp::Ordering::Less => error!("{} takes {} arguments", cmd_name, cmd.args),
-                std::cmp::Ordering::Greater => {
-                    warn!("{} only takes {} arguments", cmd_name, cmd.args);
-                    let cmd = cmd.cmd;
-
-                    cmd(args, msg_s)
-                },
-                std::cmp::Ordering::Equal => {
-                    let cmd = cmd.cmd;
-
-                    cmd(args, msg_s)
-                },
-            }
-        } else {
-            error!("{} not found", cmd_name);
-        }
-    }
-}
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 4187108814..51f4968f38 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -305,14 +305,10 @@ impl Server {
                 .min_by_key(|site_pos| site_pos.distance_squared(center_chunk))
                 .unwrap_or(center_chunk);
 
-            // calculate the absolute position of the chunk in the world
-            // (we could add TerrainChunkSize::RECT_SIZE / 2 here, to spawn in the middle of
-            // the chunk)
-            let spawn_wpos = spawn_chunk.map2(TerrainChunkSize::RECT_SIZE, |e, sz| {
-                e as i32 * sz as i32 + sz as i32 / 2
-            });
+            // Calculate the middle of the chunk in the world
+            let spawn_wpos = TerrainChunkSize::center_wpos(spawn_chunk);
 
-            // unwrapping because generate_chunk only returns err when should_continue evals
+            // Unwrapping because generate_chunk only returns err when should_continue evals
             // to true
             let (tc, _cs) = world.generate_chunk(index, spawn_chunk, || false).unwrap();
             let min_z = tc.get_min_z();
@@ -345,7 +341,7 @@ impl Server {
         #[cfg(not(feature = "worldgen"))]
         let spawn_point = Vec3::new(0.0, 0.0, 256.0);
 
-        // set the spawn point we calculated above
+        // Set the spawn point we calculated above
         state.ecs_mut().insert(SpawnPoint(spawn_point));
 
         // Insert the world into the ECS (todo: Maybe not an Arc?)
@@ -931,30 +927,63 @@ impl Server {
         self.state.ecs().read_storage::<Client>().join().count() as i64
     }
 
-    // TODO: add Admin comp if ingame
     pub fn add_admin(&self, username: &str) {
         let mut editable_settings = self.editable_settings_mut();
         let login_provider = self.state.ecs().fetch::<LoginProvider>();
         let data_dir = self.data_dir();
-        add_admin(
+        if let Some(entity) = add_admin(
             username,
             &login_provider,
             &mut editable_settings,
             &data_dir.path,
-        );
+        ).and_then(|uuid| {
+            let state = &self.state;
+            (&state.ecs().entities(), &state.read_storage::<comp::Player>())
+                .join()
+                .find(|(_, player)| player.uuid() == uuid)
+                .map(|(e, _)| e)
+        }) {
+            // Add admin component if the player is ingame
+            let _ = self.state.ecs().write_storage().insert(entity, comp::Admin);
+            
+        };
     }
 
-    // TODO: remove Admin comp if ingame
     pub fn remove_admin(&self, username: &str) {
         let mut editable_settings = self.editable_settings_mut();
         let login_provider = self.state.ecs().fetch::<LoginProvider>();
         let data_dir = self.data_dir();
-        remove_admin(
+        if let Some(entity) = remove_admin(
             username,
             &login_provider,
             &mut editable_settings,
             &data_dir.path,
-        );
+        ).and_then(|uuid| {
+            let state = &self.state;
+            (&state.ecs().entities(), &state.read_storage::<comp::Player>())
+                .join()
+                .find(|(_, player)| player.uuid() == uuid)
+                .map(|(e, _)| e)
+        }) {
+            // Remove admin component if the player is ingame
+            let _ = self.state.ecs().write_storage::<comp::Admin>().remove(entity);
+        };
+    }
+
+    /// Useful for testing without a client
+    /// view_distance: distance in chunks that are persisted, this acts like the player view
+    /// distance so it is actually a bit farther due to a buffer zone
+    pub fn create_centered_persister(&mut self, view_distance: u32) {
+        let world_dims_chunks = self.world.sim().get_size();
+        let world_dims_blocks = TerrainChunkSize::blocks(world_dims_chunks);
+        // NOTE: origin is in the corner of the map
+        // TODO: extend this function to have picking a random position or specifiying a position
+        // as options
+        //let mut rng = rand::thread_rng();
+        // // Pick a random position but not to close to the edge
+        // let rand_pos = world_dims_blocks.map(|e| e as i32).map(|e| e / 2 + rng.gen_range(-e/2..e/2 + 1));
+        let pos = comp::Pos(Vec3::from(world_dims_blocks.map(|e| e as f32 / 2.0)));
+        self.state.create_persister(pos, view_distance, &self.world, &self.index, &self.runtime).build();
     }
 }
 
@@ -966,35 +995,42 @@ impl Drop for Server {
     }
 }
 
+/// If successful returns the Some(uuid) of the added admin
 pub fn add_admin(
     username: &str,
     login_provider: &LoginProvider,
     editable_settings: &mut EditableSettings,
     data_dir: &std::path::Path,
-) {
+) -> Option<common::uuid::Uuid> {
     use crate::settings::EditableSetting;
     match login_provider.username_to_uuid(username) {
         Ok(uuid) => editable_settings.admins.edit(data_dir, |admins| {
             if admins.insert(uuid) {
                 info!("Successfully added {} ({}) as an admin!", username, uuid);
+                Some(uuid)
             } else {
                 info!("{} ({}) is already an admin!", username, uuid);
+                None
             }
         }),
-        Err(err) => error!(
-            ?err,
-            "Could not find uuid for this name either the user does not exist or there was an \
-             error communicating with the auth server."
-        ),
+        Err(err) => {
+             error!(
+                ?err,
+                "Could not find uuid for this name either the user does not exist or there was an \
+                 error communicating with the auth server."
+            );
+            None
+        },
     }
 }
 
+/// If successful returns the Some(uuid) of the removed admin
 pub fn remove_admin(
     username: &str,
     login_provider: &LoginProvider,
     editable_settings: &mut EditableSettings,
     data_dir: &std::path::Path,
-) {
+) -> Option<common::uuid::Uuid> {
     use crate::settings::EditableSetting;
     match login_provider.username_to_uuid(username) {
         Ok(uuid) => editable_settings.admins.edit(data_dir, |admins| {
@@ -1003,14 +1039,19 @@ pub fn remove_admin(
                     "Successfully removed {} ({}) from the admins",
                     username, uuid
                 );
+                Some(uuid)
             } else {
                 info!("{} ({}) is not an admin!", username, uuid);
+                None
             }
         }),
-        Err(err) => error!(
-            ?err,
-            "Could not find uuid for this name either the user does not exist or there was an \
-             error communicating with the auth server."
-        ),
+        Err(err) => {
+            error!(
+                ?err,
+                "Could not find uuid for this name either the user does not exist or there was an \
+                 error communicating with the auth server."
+            ); 
+            None
+        },
     }
 }
diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs
index 379fb920e5..a596b31cbb 100644
--- a/server/src/state_ext.rs
+++ b/server/src/state_ext.rs
@@ -63,6 +63,18 @@ pub trait StateExt {
         pos: comp::Pos,
         ori: comp::Ori,
     ) -> EcsEntityBuilder;
+    // NOTE: currently only used for testing
+    /// Queues chunk generation in the view distance of the persister, this
+    /// entity must be built before those chunks are received (the builder
+    /// borrows the ecs world so that is kind of impossible in practice)
+    fn create_persister(
+        &mut self,
+        pos: comp::Pos,
+        view_distance: u32,
+        world: &std::sync::Arc<world::World>,
+        index: &world::IndexOwned,
+        runtime: &tokio::runtime::Runtime,
+    ) -> EcsEntityBuilder;
     /// Insert common/default components for a new character joining the server
     fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId);
     /// Update the components associated with the entity's current character.
@@ -257,6 +269,50 @@ impl StateExt for State {
             })
     }
 
+    // NOTE: currently only used for testing
+    /// Queues chunk generation in the view distance of the persister, this
+    /// entity must be built before those chunks are received (the builder
+    /// borrows the ecs world so that is kind of impossible in practice)
+    fn create_persister(
+        &mut self,
+        pos: comp::Pos,
+        view_distance: u32,
+        world: &std::sync::Arc<world::World>,
+        index: &world::IndexOwned,
+        runtime: &tokio::runtime::Runtime,
+    ) -> EcsEntityBuilder {
+        use common::{terrain::TerrainChunkSize, vol::RectVolSize};
+        use std::sync::Arc;
+        // Request chunks
+        {
+            let mut chunk_generator = self
+                .ecs()
+                .write_resource::<crate::chunk_generator::ChunkGenerator>();
+            let chunk_pos = self.terrain().pos_key(pos.0.map(|e| e as i32));
+            (-(view_distance as i32)..view_distance as i32 + 1)
+            .flat_map(|x| {
+                (-(view_distance as i32)..view_distance as i32 + 1).map(move |y| Vec2::new(x, y))
+            })
+            .map(|offset| offset + chunk_pos)
+            // Filter chunks outside the view distance
+            // Note: calculation from client chunk request filtering
+            .filter(|chunk_key| {
+                pos.0.xy().map(|e| e as f64).distance(
+                    chunk_key.map(|e| e as f64 + 0.5) * TerrainChunkSize::RECT_SIZE.map(|e| e as f64),
+                ) < (view_distance as f64 - 1.0 + 2.5 * 2.0_f64.sqrt())
+                    * TerrainChunkSize::RECT_SIZE.x as f64
+            })
+            .for_each(|chunk_key| {
+                chunk_generator.generate_chunk(None, chunk_key, runtime, Arc::clone(world), index.clone());
+            });
+        }
+
+        self.ecs_mut()
+            .create_entity_synced()
+            .with(pos)
+            .with(Presence::new(view_distance, PresenceKind::Spectator))
+    }
+
     fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId) {
         let spawn_point = self.ecs().read_resource::<SpawnPoint>().0;
 
diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs
index dd029b3546..40059f5a28 100644
--- a/server/src/sys/agent.rs
+++ b/server/src/sys/agent.rs
@@ -23,6 +23,7 @@ use common::{
     util::Dir,
     vol::ReadVol,
 };
+use common_base::prof_span;
 use common_ecs::{Job, Origin, ParMode, Phase, System};
 use rand::{thread_rng, Rng};
 use rayon::iter::ParallelIterator;
@@ -141,8 +142,13 @@ impl<'a> System<'a> for Sys {
                     .map(|ms| *ms == MountState::Unmounted)
                     .unwrap_or(true)
             })
-            .for_each(
-                |(
+            .for_each_init(
+                || {
+                    prof_span!(guard, "agent rayon job");
+                    guard
+                },
+                |_guard,
+                 (
                     entity,
                     (energy, health),
                     pos,
diff --git a/voxygen/src/logging.rs b/voxygen/src/logging.rs
index e8569be402..5039c94316 100644
--- a/voxygen/src/logging.rs
+++ b/voxygen/src/logging.rs
@@ -43,10 +43,10 @@ pub fn init(settings: &Settings) -> Vec<impl Drop> {
         env.add_directive("dot_vox::parser=warn".parse().unwrap())
             .add_directive("gfx_device_gl=warn".parse().unwrap())
             .add_directive("prometheus_hyper=warn".parse().unwrap())
-            .add_directive("mio::sys::windows=debug".parse().unwrap())
+            .add_directive("mio::sys::windows=info".parse().unwrap())
             .add_directive("h2=info".parse().unwrap())
             .add_directive("tokio_util=info".parse().unwrap())
-            .add_directive("rustls=debug".parse().unwrap())
+            .add_directive("rustls=info".parse().unwrap())
             .add_directive("veloren_network_protocol=info".parse().unwrap())
             .add_directive(
                 "veloren_server::persistence::character=info"

From 26df88bcdb1d0dedaa2926029f15d18c61965ae3 Mon Sep 17 00:00:00 2001
From: Imbris <imbrisf@gmail.com>
Date: Sat, 13 Mar 2021 02:59:58 -0500
Subject: [PATCH 2/3] Add tracy entity count plot, span tweaks

---
 common/src/ray.rs     | 2 --
 server-cli/Cargo.toml | 2 +-
 server/Cargo.toml     | 1 +
 server/src/lib.rs     | 9 +++++++++
 4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/common/src/ray.rs b/common/src/ray.rs
index 60eef65a05..2188658269 100644
--- a/common/src/ray.rs
+++ b/common/src/ray.rs
@@ -1,5 +1,4 @@
 use crate::vol::ReadVol;
-use common_base::span;
 use vek::*;
 
 pub trait RayForEach<V> = FnMut(&V, Vec3<i32>);
@@ -62,7 +61,6 @@ impl<'a, V: ReadVol, F: FnMut(&V::Vox) -> bool, G: RayForEach<V::Vox>> Ray<'a, V
     }
 
     pub fn cast(mut self) -> (f32, Result<Option<&'a V::Vox>, V::Error>) {
-        span!(_guard, "cast", "Ray::cast");
         // TODO: Fully test this!
 
         const PLANCK: f32 = 0.001;
diff --git a/server-cli/Cargo.toml b/server-cli/Cargo.toml
index 4ea9b517f5..551295e18a 100644
--- a/server-cli/Cargo.toml
+++ b/server-cli/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2018"
 [features]
 worldgen = ["server/worldgen"]
 default = ["worldgen"]
-tracy = ["common/tracy", "tracing-tracy"]
+tracy = ["common/tracy", "tracing-tracy", "server/tracy"]
 plugins = ["server/plugins"]
 
 [dependencies]
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 4472f5ece3..91f08d0356 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2018"
 
 [features]
 worldgen = []
+tracy = ["common/tracy"]
 simd = ["vek/platform_intrinsics"]
 plugins = ["common-sys/plugins"]
 
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 51f4968f38..482a913c7b 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -702,6 +702,15 @@ impl Server {
                 .set((end_of_server_tick - before_persistence_updates).as_nanos() as i64);
         }
 
+        #[cfg(feature = "tracy")]
+        {
+            use common_base::tracy_client::Plot;
+            use common_base::tracy_client::create_plot;
+            let entity_count = self.state.ecs().entities().join().count();
+            static ENTITY_COUNT: Plot = create_plot!("entity count");
+            ENTITY_COUNT.point(entity_count as f64);
+        }
+
         // 9) Finish the tick, pass control back to the frontend.
 
         Ok(frontend_events)

From aff3536ac996bb4224f0acc8a4c81be272a91056 Mon Sep 17 00:00:00 2001
From: Imbris <imbrisf@gmail.com>
Date: Sat, 13 Mar 2021 11:21:02 -0500
Subject: [PATCH 3/3] Fix tracy not working in certain areas, add span to chunk
 gen, missing fmt, remove extra span, make voxygen use INFO level instead of
 TRACE in tracy mode

---
 client/Cargo.toml             |  1 +
 common/ecs/Cargo.toml         |  3 ++-
 common/ecs/src/system.rs      |  5 +---
 common/src/comp/phys.rs       |  2 ++
 common/src/terrain/mod.rs     |  6 +++++
 server-cli/Cargo.toml         |  2 +-
 server/Cargo.toml             |  2 +-
 server/src/chunk_generator.rs |  1 +
 server/src/lib.rs             | 48 ++++++++++++++++++++++-------------
 voxygen/Cargo.toml            |  2 +-
 voxygen/src/logging.rs        |  2 +-
 world/Cargo.toml              |  2 ++
 12 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/client/Cargo.toml b/client/Cargo.toml
index 48d369472f..366bc4c7de 100644
--- a/client/Cargo.toml
+++ b/client/Cargo.toml
@@ -5,6 +5,7 @@ authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
 edition = "2018"
 
 [features]
+tracy = ["common/tracy", "common-base/tracy", "common-sys/tracy", "common-net/tracy"]
 simd = ["vek/platform_intrinsics"]
 plugins = ["common-sys/plugins"]
 bin_bot = ["common-ecs", "serde", "ron", "clap", "rustyline", "termcolor", "tracing-subscriber", "async-channel"]
diff --git a/common/ecs/Cargo.toml b/common/ecs/Cargo.toml
index 4e7c584254..342d0de80b 100644
--- a/common/ecs/Cargo.toml
+++ b/common/ecs/Cargo.toml
@@ -5,6 +5,7 @@ name = "veloren-common-ecs"
 version = "0.8.0"
 
 [features]
+tracy = ["common-base/tracy"]
 
 [dependencies]
 
@@ -16,4 +17,4 @@ specs = { git = "https://github.com/amethyst/specs.git", features = ["serde", "s
 
 [dev-dependencies]
 #bench
-float-cmp = "0.8.0"
\ No newline at end of file
+float-cmp = "0.8.0"
diff --git a/common/ecs/src/system.rs b/common/ecs/src/system.rs
index 033ed7818d..f1459967f4 100644
--- a/common/ecs/src/system.rs
+++ b/common/ecs/src/system.rs
@@ -253,10 +253,7 @@ where
     fn run(&mut self, data: Self::SystemData) {
         common_base::span!(_guard, "run", &format!("{}::Sys::run", T::NAME));
         self.cpu_stats.reset();
-        {
-            common_base::span!(_guard, "run inner", &format!("{}::Sys::run inner", T::NAME));
-            T::run(self, data.0);
-        }
+        T::run(self, data.0);
         self.cpu_stats.end();
         data.1
             .stats
diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs
index 7731c4a0b5..fdb8d10a05 100644
--- a/common/src/comp/phys.rs
+++ b/common/src/comp/phys.rs
@@ -26,6 +26,8 @@ impl Component for Vel {
 #[derive(Copy, Clone, Default, Debug, PartialEq)]
 pub struct PreviousPhysCache {
     pub velocity_dt: Vec3<f32>,
+    /// Center of bounding sphere that encompasses the entity along its path for
+    /// this tick
     pub center: Vec3<f32>,
     /// Calculates a Sphere over the Entity for quick boundary checking
     pub collision_boundary: f32,
diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs
index b108d302c3..5360b6c7c8 100644
--- a/common/src/terrain/mod.rs
+++ b/common/src/terrain/mod.rs
@@ -53,6 +53,9 @@ impl TerrainChunkSize {
     #[inline(always)]
     /// Convert dimensions in terms of chunks into dimensions in terms of blocks
     /// ```
+    /// use vek::*;
+    /// use veloren_common::terrain::TerrainChunkSize;
+    ///
     /// assert_eq!(TerrainChunkSize::blocks(Vec2::new(3, 2)), Vec2::new(96, 64));
     /// ```
     pub fn blocks(chunks: Vec2<u32>) -> Vec2<u32> { chunks * Self::RECT_SIZE }
@@ -60,6 +63,9 @@ impl TerrainChunkSize {
     /// Calculate the world position (i.e. in blocks) at the center of this
     /// chunk
     /// ```
+    /// use vek::*;
+    /// use veloren_common::terrain::TerrainChunkSize;
+    ///
     /// assert_eq!(
     ///     TerrainChunkSize::center_wpos(Vec2::new(0, 2)),
     ///     Vec2::new(16, 80)
diff --git a/server-cli/Cargo.toml b/server-cli/Cargo.toml
index 551295e18a..4fc4646e65 100644
--- a/server-cli/Cargo.toml
+++ b/server-cli/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2018"
 [features]
 worldgen = ["server/worldgen"]
 default = ["worldgen"]
-tracy = ["common/tracy", "tracing-tracy", "server/tracy"]
+tracy = ["common/tracy", "tracing-tracy", "server/tracy", "common-net/tracy"]
 plugins = ["server/plugins"]
 
 [dependencies]
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 91f08d0356..b2634cf066 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2018"
 
 [features]
 worldgen = []
-tracy = ["common/tracy"]
+tracy = ["common/tracy", "common-base/tracy", "common-ecs/tracy", "common-sys/tracy", "common-net/tracy", "world/tracy"]
 simd = ["vek/platform_intrinsics"]
 plugins = ["common-sys/plugins"]
 
diff --git a/server/src/chunk_generator.rs b/server/src/chunk_generator.rs
index 556ba08bdd..de28f441c3 100644
--- a/server/src/chunk_generator.rs
+++ b/server/src/chunk_generator.rs
@@ -54,6 +54,7 @@ impl ChunkGenerator {
         let chunk_tx = self.chunk_tx.clone();
         self.metrics.chunks_requested.inc();
         runtime.spawn_blocking(move || {
+            common_base::prof_span!(_guard, "generate_chunk");
             let index = index.as_index_ref();
             let payload = world
                 .generate_chunk(index, key, || cancel.load(Ordering::Relaxed))
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 482a913c7b..05179fb637 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -540,7 +540,7 @@ impl Server {
             (
                 &self.state.ecs().entities(),
                 &self.state.ecs().read_storage::<comp::Pos>(),
-                !&self.state.ecs().read_storage::<comp::Player>(),
+                !&self.state.ecs().read_storage::<Presence>(),
                 self.state.ecs().read_storage::<comp::HomeChunk>().maybe(),
             )
                 .join()
@@ -704,8 +704,7 @@ impl Server {
 
         #[cfg(feature = "tracy")]
         {
-            use common_base::tracy_client::Plot;
-            use common_base::tracy_client::create_plot;
+            use common_base::tracy_client::{create_plot, Plot};
             let entity_count = self.state.ecs().entities().join().count();
             static ENTITY_COUNT: Plot = create_plot!("entity count");
             ENTITY_COUNT.point(entity_count as f64);
@@ -945,16 +944,19 @@ impl Server {
             &login_provider,
             &mut editable_settings,
             &data_dir.path,
-        ).and_then(|uuid| {
+        )
+        .and_then(|uuid| {
             let state = &self.state;
-            (&state.ecs().entities(), &state.read_storage::<comp::Player>())
+            (
+                &state.ecs().entities(),
+                &state.read_storage::<comp::Player>(),
+            )
                 .join()
                 .find(|(_, player)| player.uuid() == uuid)
                 .map(|(e, _)| e)
         }) {
             // Add admin component if the player is ingame
             let _ = self.state.ecs().write_storage().insert(entity, comp::Admin);
-            
         };
     }
 
@@ -967,32 +969,44 @@ impl Server {
             &login_provider,
             &mut editable_settings,
             &data_dir.path,
-        ).and_then(|uuid| {
+        )
+        .and_then(|uuid| {
             let state = &self.state;
-            (&state.ecs().entities(), &state.read_storage::<comp::Player>())
+            (
+                &state.ecs().entities(),
+                &state.read_storage::<comp::Player>(),
+            )
                 .join()
                 .find(|(_, player)| player.uuid() == uuid)
                 .map(|(e, _)| e)
         }) {
             // Remove admin component if the player is ingame
-            let _ = self.state.ecs().write_storage::<comp::Admin>().remove(entity);
+            let _ = self
+                .state
+                .ecs()
+                .write_storage::<comp::Admin>()
+                .remove(entity);
         };
     }
 
     /// Useful for testing without a client
-    /// view_distance: distance in chunks that are persisted, this acts like the player view
-    /// distance so it is actually a bit farther due to a buffer zone
+    /// view_distance: distance in chunks that are persisted, this acts like the
+    /// player view distance so it is actually a bit farther due to a buffer
+    /// zone
     pub fn create_centered_persister(&mut self, view_distance: u32) {
         let world_dims_chunks = self.world.sim().get_size();
         let world_dims_blocks = TerrainChunkSize::blocks(world_dims_chunks);
         // NOTE: origin is in the corner of the map
-        // TODO: extend this function to have picking a random position or specifiying a position
-        // as options
+        // TODO: extend this function to have picking a random position or specifiying a
+        // position as options
         //let mut rng = rand::thread_rng();
         // // Pick a random position but not to close to the edge
-        // let rand_pos = world_dims_blocks.map(|e| e as i32).map(|e| e / 2 + rng.gen_range(-e/2..e/2 + 1));
+        // let rand_pos = world_dims_blocks.map(|e| e as i32).map(|e| e / 2 +
+        // rng.gen_range(-e/2..e/2 + 1));
         let pos = comp::Pos(Vec3::from(world_dims_blocks.map(|e| e as f32 / 2.0)));
-        self.state.create_persister(pos, view_distance, &self.world, &self.index, &self.runtime).build();
+        self.state
+            .create_persister(pos, view_distance, &self.world, &self.index, &self.runtime)
+            .build();
     }
 }
 
@@ -1023,7 +1037,7 @@ pub fn add_admin(
             }
         }),
         Err(err) => {
-             error!(
+            error!(
                 ?err,
                 "Could not find uuid for this name either the user does not exist or there was an \
                  error communicating with the auth server."
@@ -1059,7 +1073,7 @@ pub fn remove_admin(
                 ?err,
                 "Could not find uuid for this name either the user does not exist or there was an \
                  error communicating with the auth server."
-            ); 
+            );
             None
         },
     }
diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml
index 2b42391995..4c9d5342e6 100644
--- a/voxygen/Cargo.toml
+++ b/voxygen/Cargo.toml
@@ -13,7 +13,7 @@ gl = ["gfx_device_gl", "gfx_gl"]
 hot-anim = ["anim/use-dyn-lib"]
 singleplayer = ["server"]
 simd = ["vek/platform_intrinsics"]
-tracy = ["tracing-tracy", "common/tracy"]
+tracy = ["tracing-tracy", "common/tracy", "common-ecs/tracy", "common-net/tracy", "common-sys/tracy", "client/tracy"]
 plugins = ["client/plugins"]
 
 default = ["gl", "singleplayer", "native-dialog", "plugins", "simd"]
diff --git a/voxygen/src/logging.rs b/voxygen/src/logging.rs
index 5039c94316..f0b3817b71 100644
--- a/voxygen/src/logging.rs
+++ b/voxygen/src/logging.rs
@@ -72,7 +72,7 @@ pub fn init(settings: &Settings) -> Vec<impl Drop> {
     };
 
     #[cfg(feature = "tracy")]
-    let filter = base_exceptions(EnvFilter::new("")).add_directive(LevelFilter::TRACE.into());
+    let filter = base_exceptions(EnvFilter::new("")).add_directive(LevelFilter::INFO.into());
 
     // Create the terminal writer layer.
     let (non_blocking, _stdio_guard) =
diff --git a/world/Cargo.toml b/world/Cargo.toml
index 4f5e5eb48d..316e46ee25 100644
--- a/world/Cargo.toml
+++ b/world/Cargo.toml
@@ -5,6 +5,7 @@ authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
 edition = "2018"
 
 [features]
+tracy = ["common/tracy", "common-net/tracy"]
 simd = ["vek/platform_intrinsics"]
 
 default = ["simd"]
@@ -12,6 +13,7 @@ default = ["simd"]
 [dependencies]
 common = { package = "veloren-common", path = "../common" }
 common-net = { package = "veloren-common-net", path = "../common/net" }
+
 bincode = "1.3.1"
 bitvec = "0.21.0"
 enum-iterator = "0.6"