From ba7d7481d7c4ba8b7839123209791db891208434 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sun, 4 Jun 2023 12:32:09 -0400 Subject: [PATCH] Move RegionMap insertion into ecs and ticking from `common` into `server` Since it now needs Presence component to be available and we don't use the RegionMap on the client. --- common/state/src/state.rs | 28 +++++----------------------- server/src/lib.rs | 18 +++++++++++++++++- server/src/sys/entity_sync.rs | 8 ++++++++ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/common/state/src/state.rs b/common/state/src/state.rs index 6c1ee98404..01a1e23b31 100644 --- a/common/state/src/state.rs +++ b/common/state/src/state.rs @@ -12,7 +12,6 @@ use common::{ link::Is, mounting::{Mount, Rider, VolumeRider, VolumeRiders}, outcome::Outcome, - region::RegionMap, resources::{ DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, Time, TimeOfDay, TimeScale, @@ -294,7 +293,6 @@ impl State { // TODO: only register on the server ecs.insert(EventBus::::default()); ecs.insert(comp::group::GroupManager::default()); - ecs.insert(RegionMap::new()); ecs.insert(SysMetrics::default()); ecs.insert(PhysicsMetrics::default()); ecs.insert(Trades::default()); @@ -528,17 +526,6 @@ impl State { } } - // Run RegionMap tick to update entity region occupancy - pub fn update_region_map(&self) { - span!(_guard, "update_region_map", "State::update_region_map"); - self.ecs.write_resource::().tick( - self.ecs.read_storage::(), - self.ecs.read_storage::(), - self.ecs.read_storage::(), - self.ecs.entities(), - ); - } - // Apply terrain changes pub fn apply_terrain_changes(&self, block_update: impl FnMut(&specs::World, Vec)) { self.apply_terrain_changes_internal(false, block_update); @@ -548,10 +535,9 @@ impl State { /// [State::tick]. /// /// This only happens if [State::tick] is asked to update terrain itself - /// (using `update_terrain_and_regions: true`). [State::tick] is called - /// from within both the client and the server ticks, right after - /// handling terrain messages; currently, client sets it to true and - /// server to false. + /// (using `update_terrain: true`). [State::tick] is called from within + /// both the client and the server ticks, right after handling terrain + /// messages; currently, client sets it to true and server to false. fn apply_terrain_changes_internal( &self, during_tick: bool, @@ -629,7 +615,7 @@ impl State { &mut self, dt: Duration, add_systems: impl Fn(&mut DispatcherBuilder), - update_terrain_and_regions: bool, + update_terrain: bool, mut metrics: Option<&mut StateTickMetrics>, server_constants: &ServerConstants, block_update: impl FnMut(&specs::World, Vec), @@ -657,10 +643,6 @@ impl State { self.ecs.write_resource::().0 = (dt.as_secs_f32() * time_scale as f32).min(MAX_DELTA_TIME); - if update_terrain_and_regions { - self.update_region_map(); - } - section_span!(guard, "create dispatcher"); // Run systems to update the world. // Create and run a dispatcher for ecs systems. @@ -680,7 +662,7 @@ impl State { self.ecs.maintain(); drop(guard); - if update_terrain_and_regions { + if update_terrain { self.apply_terrain_changes_internal(true, block_update); } diff --git a/server/src/lib.rs b/server/src/lib.rs index 1392abcfe3..4b19c3af17 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -76,6 +76,7 @@ use common::{ cmd::ServerChatCommand, comp, event::{EventBus, ServerEvent}, + region::RegionMap, resources::{BattleMode, GameMode, Time, TimeOfDay}, rtsim::{RtSimEntity, RtSimVehicle}, shared_server_config::ServerConstants, @@ -377,6 +378,9 @@ impl Server { .ecs_mut() .insert(sys::PersistenceScheduler::every(Duration::from_secs(10))); + // Region map (spatial structure for entity synchronization) + state.ecs_mut().insert(RegionMap::new()); + // Server-only components state.ecs_mut().register::(); state.ecs_mut().register::(); @@ -754,7 +758,7 @@ impl Server { // events so that changes made by server events will be immediately // visible to client synchronization systems, minimizing the latency of // `ServerEvent` mediated effects - self.state.update_region_map(); + self.update_region_map(); // NOTE: apply_terrain_changes sends the *new* value since it is not being // synchronized during the tick. self.state.apply_terrain_changes(on_block_update); @@ -1092,6 +1096,18 @@ impl Server { .map(|mut t| t.maintain()); } + // Run RegionMap tick to update entity region occupancy + fn update_region_map(&mut self) { + prof_span!("Server::update_region_map"); + let ecs = self.state().ecs(); + ecs.write_resource::().tick( + ecs.read_storage::(), + ecs.read_storage::(), + ecs.read_storage::(), + ecs.entities(), + ); + } + fn initialize_client(&mut self, client: connection_handler::IncomingClient) -> Entity { let entity = self .state diff --git a/server/src/sys/entity_sync.rs b/server/src/sys/entity_sync.rs index 2d4458d01a..7d5feff755 100644 --- a/server/src/sys/entity_sync.rs +++ b/server/src/sys/entity_sync.rs @@ -372,6 +372,14 @@ impl<'a> System<'a> for Sys { )); } + // TODO: this seems like the ideal spot to sync other components for clients + // that don't have a position or otherwise aren't included in the regions that + // the client is subscribed to... + // + // Maybe we can pass a bool into `create_sync_from_client_package`... renamed it + // to create_sync_package_for_client_entity(?) + // create_client_sync_package(?) + // // Sync components that are only synced for the client's own entity. for (entity, client) in (&entities, &clients).join() { let comp_sync_package =