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.
This commit is contained in:
Imbris 2023-06-04 12:32:09 -04:00
parent a01f75b38d
commit ba7d7481d7
3 changed files with 30 additions and 24 deletions

View File

@ -12,7 +12,6 @@ use common::{
link::Is, link::Is,
mounting::{Mount, Rider, VolumeRider, VolumeRiders}, mounting::{Mount, Rider, VolumeRider, VolumeRiders},
outcome::Outcome, outcome::Outcome,
region::RegionMap,
resources::{ resources::{
DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, Time, DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, Time,
TimeOfDay, TimeScale, TimeOfDay, TimeScale,
@ -294,7 +293,6 @@ impl State {
// TODO: only register on the server // TODO: only register on the server
ecs.insert(EventBus::<ServerEvent>::default()); ecs.insert(EventBus::<ServerEvent>::default());
ecs.insert(comp::group::GroupManager::default()); ecs.insert(comp::group::GroupManager::default());
ecs.insert(RegionMap::new());
ecs.insert(SysMetrics::default()); ecs.insert(SysMetrics::default());
ecs.insert(PhysicsMetrics::default()); ecs.insert(PhysicsMetrics::default());
ecs.insert(Trades::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::<RegionMap>().tick(
self.ecs.read_storage::<comp::Pos>(),
self.ecs.read_storage::<comp::Vel>(),
self.ecs.read_storage::<comp::Presence>(),
self.ecs.entities(),
);
}
// Apply terrain changes // Apply terrain changes
pub fn apply_terrain_changes(&self, block_update: impl FnMut(&specs::World, Vec<BlockDiff>)) { pub fn apply_terrain_changes(&self, block_update: impl FnMut(&specs::World, Vec<BlockDiff>)) {
self.apply_terrain_changes_internal(false, block_update); self.apply_terrain_changes_internal(false, block_update);
@ -548,10 +535,9 @@ impl State {
/// [State::tick]. /// [State::tick].
/// ///
/// This only happens if [State::tick] is asked to update terrain itself /// This only happens if [State::tick] is asked to update terrain itself
/// (using `update_terrain_and_regions: true`). [State::tick] is called /// (using `update_terrain: true`). [State::tick] is called from within
/// from within both the client and the server ticks, right after /// both the client and the server ticks, right after handling terrain
/// handling terrain messages; currently, client sets it to true and /// messages; currently, client sets it to true and server to false.
/// server to false.
fn apply_terrain_changes_internal( fn apply_terrain_changes_internal(
&self, &self,
during_tick: bool, during_tick: bool,
@ -629,7 +615,7 @@ impl State {
&mut self, &mut self,
dt: Duration, dt: Duration,
add_systems: impl Fn(&mut DispatcherBuilder), add_systems: impl Fn(&mut DispatcherBuilder),
update_terrain_and_regions: bool, update_terrain: bool,
mut metrics: Option<&mut StateTickMetrics>, mut metrics: Option<&mut StateTickMetrics>,
server_constants: &ServerConstants, server_constants: &ServerConstants,
block_update: impl FnMut(&specs::World, Vec<BlockDiff>), block_update: impl FnMut(&specs::World, Vec<BlockDiff>),
@ -657,10 +643,6 @@ impl State {
self.ecs.write_resource::<DeltaTime>().0 = self.ecs.write_resource::<DeltaTime>().0 =
(dt.as_secs_f32() * time_scale as f32).min(MAX_DELTA_TIME); (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"); section_span!(guard, "create dispatcher");
// Run systems to update the world. // Run systems to update the world.
// Create and run a dispatcher for ecs systems. // Create and run a dispatcher for ecs systems.
@ -680,7 +662,7 @@ impl State {
self.ecs.maintain(); self.ecs.maintain();
drop(guard); drop(guard);
if update_terrain_and_regions { if update_terrain {
self.apply_terrain_changes_internal(true, block_update); self.apply_terrain_changes_internal(true, block_update);
} }

View File

@ -76,6 +76,7 @@ use common::{
cmd::ServerChatCommand, cmd::ServerChatCommand,
comp, comp,
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
region::RegionMap,
resources::{BattleMode, GameMode, Time, TimeOfDay}, resources::{BattleMode, GameMode, Time, TimeOfDay},
rtsim::{RtSimEntity, RtSimVehicle}, rtsim::{RtSimEntity, RtSimVehicle},
shared_server_config::ServerConstants, shared_server_config::ServerConstants,
@ -377,6 +378,9 @@ impl Server {
.ecs_mut() .ecs_mut()
.insert(sys::PersistenceScheduler::every(Duration::from_secs(10))); .insert(sys::PersistenceScheduler::every(Duration::from_secs(10)));
// Region map (spatial structure for entity synchronization)
state.ecs_mut().insert(RegionMap::new());
// Server-only components // Server-only components
state.ecs_mut().register::<RegionSubscription>(); state.ecs_mut().register::<RegionSubscription>();
state.ecs_mut().register::<Client>(); state.ecs_mut().register::<Client>();
@ -754,7 +758,7 @@ impl Server {
// events so that changes made by server events will be immediately // events so that changes made by server events will be immediately
// visible to client synchronization systems, minimizing the latency of // visible to client synchronization systems, minimizing the latency of
// `ServerEvent` mediated effects // `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 // NOTE: apply_terrain_changes sends the *new* value since it is not being
// synchronized during the tick. // synchronized during the tick.
self.state.apply_terrain_changes(on_block_update); self.state.apply_terrain_changes(on_block_update);
@ -1092,6 +1096,18 @@ impl Server {
.map(|mut t| t.maintain()); .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::<RegionMap>().tick(
ecs.read_storage::<comp::Pos>(),
ecs.read_storage::<comp::Vel>(),
ecs.read_storage::<comp::Presence>(),
ecs.entities(),
);
}
fn initialize_client(&mut self, client: connection_handler::IncomingClient) -> Entity { fn initialize_client(&mut self, client: connection_handler::IncomingClient) -> Entity {
let entity = self let entity = self
.state .state

View File

@ -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. // Sync components that are only synced for the client's own entity.
for (entity, client) in (&entities, &clients).join() { for (entity, client) in (&entities, &clients).join() {
let comp_sync_package = let comp_sync_package =