From 1a484410ca3499040ceeff095d29ed880db46020 Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 18 Mar 2020 17:00:07 -0400 Subject: [PATCH] Delete Vel and Ori on the client when they are removed on the server --- client/src/lib.rs | 34 ++---- common/src/msg/ecs_packet.rs | 15 +++ common/src/msg/server.rs | 19 +-- common/src/sync/mod.rs | 4 +- common/src/sync/packet.rs | 56 +++++++-- common/src/sync/sync_ext.rs | 36 +++--- server/src/lib.rs | 2 +- server/src/sys/entity_sync.rs | 216 +++++++++++++-------------------- server/src/sys/sentinel.rs | 28 +++-- server/src/sys/subscription.rs | 37 +++--- 10 files changed, 219 insertions(+), 228 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 0b97b35bc8..c6008fcc94 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -629,8 +629,15 @@ impl Client { ServerMsg::TimeOfDay(time_of_day) => { *self.state.ecs_mut().write_resource() = time_of_day; }, - ServerMsg::EcsSync(sync_package) => { - self.state.ecs_mut().apply_sync_package(sync_package); + ServerMsg::EntitySync(entity_sync_package) => { + self.state + .ecs_mut() + .apply_entity_sync_package(entity_sync_package); + }, + ServerMsg::CompSync(comp_sync_package) => { + self.state + .ecs_mut() + .apply_comp_sync_package(comp_sync_package); }, ServerMsg::CreateEntity(entity_package) => { self.state.ecs_mut().apply_entity_package(entity_package); @@ -667,29 +674,6 @@ impl Client { .allocate(entity_builder.entity, Some(client_uid)); self.entity = entity_builder.with(uid).build(); }, - ServerMsg::EntityPos { entity, pos } => { - if let Some(entity) = self.state.ecs().entity_from_uid(entity) { - self.state.write_component(entity, pos); - } - }, - ServerMsg::EntityVel { entity, vel } => { - if let Some(entity) = self.state.ecs().entity_from_uid(entity) { - self.state.write_component(entity, vel); - } - }, - ServerMsg::EntityOri { entity, ori } => { - if let Some(entity) = self.state.ecs().entity_from_uid(entity) { - self.state.write_component(entity, ori); - } - }, - ServerMsg::EntityCharacterState { - entity, - character_state, - } => { - if let Some(entity) = self.state.ecs().entity_from_uid(entity) { - self.state.write_component(entity, character_state); - } - }, ServerMsg::InventoryUpdate(inventory, event) => { match event { InventoryUpdateEvent::CollectFailed => { diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 4034c6b953..31a80fa727 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -25,6 +25,9 @@ sum_type! { Loadout(comp::Loadout), Attacking(comp::Attacking), CharacterState(comp::CharacterState), + Pos(comp::Pos), + Vel(comp::Vel), + Ori(comp::Ori), } } // Automatically derive From for EcsCompPhantom @@ -49,6 +52,9 @@ sum_type! { Loadout(PhantomData), Attacking(PhantomData), CharacterState(PhantomData), + Pos(PhantomData), + Vel(PhantomData), + Ori(PhantomData), } } impl sync::CompPacket for EcsCompPacket { @@ -73,6 +79,9 @@ impl sync::CompPacket for EcsCompPacket { EcsCompPacket::Loadout(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::Attacking(comp) => sync::handle_insert(comp, entity, world), EcsCompPacket::CharacterState(comp) => sync::handle_insert(comp, entity, world), + EcsCompPacket::Pos(comp) => sync::handle_insert(comp, entity, world), + EcsCompPacket::Vel(comp) => sync::handle_insert(comp, entity, world), + EcsCompPacket::Ori(comp) => sync::handle_insert(comp, entity, world), } } @@ -95,6 +104,9 @@ impl sync::CompPacket for EcsCompPacket { EcsCompPacket::Loadout(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::Attacking(comp) => sync::handle_modify(comp, entity, world), EcsCompPacket::CharacterState(comp) => sync::handle_modify(comp, entity, world), + EcsCompPacket::Pos(comp) => sync::handle_modify(comp, entity, world), + EcsCompPacket::Vel(comp) => sync::handle_modify(comp, entity, world), + EcsCompPacket::Ori(comp) => sync::handle_modify(comp, entity, world), } } @@ -123,6 +135,9 @@ impl sync::CompPacket for EcsCompPacket { EcsCompPhantom::CharacterState(_) => { sync::handle_remove::(entity, world) }, + EcsCompPhantom::Pos(_) => sync::handle_remove::(entity, world), + EcsCompPhantom::Vel(_) => sync::handle_remove::(entity, world), + EcsCompPhantom::Ori(_) => sync::handle_remove::(entity, world), } } } diff --git a/common/src/msg/server.rs b/common/src/msg/server.rs index c517eec665..5e6fecac33 100644 --- a/common/src/msg/server.rs +++ b/common/src/msg/server.rs @@ -46,25 +46,10 @@ pub enum ServerMsg { }, SetPlayerEntity(u64), TimeOfDay(state::TimeOfDay), - EcsSync(sync::SyncPackage), + EntitySync(sync::EntitySyncPackage), + CompSync(sync::CompSyncPackage), CreateEntity(sync::EntityPackage), DeleteEntity(u64), - EntityPos { - entity: u64, - pos: comp::Pos, - }, - EntityVel { - entity: u64, - vel: comp::Vel, - }, - EntityOri { - entity: u64, - ori: comp::Ori, - }, - EntityCharacterState { - entity: u64, - character_state: comp::CharacterState, - }, InventoryUpdate(comp::Inventory, comp::InventoryUpdateEvent), TerrainChunkUpdate { key: Vec2, diff --git a/common/src/sync/mod.rs b/common/src/sync/mod.rs index cce991d1df..914793c024 100644 --- a/common/src/sync/mod.rs +++ b/common/src/sync/mod.rs @@ -7,8 +7,8 @@ mod uid; // Reexports pub use packet::{ - handle_insert, handle_modify, handle_remove, CompPacket, EntityPackage, StatePackage, - SyncPackage, + handle_insert, handle_modify, handle_remove, CompPacket, CompSyncPackage, EntityPackage, + EntitySyncPackage, StatePackage, }; pub use sync_ext::WorldSyncExt; pub use track::UpdateTracker; diff --git a/common/src/sync/packet.rs b/common/src/sync/packet.rs index ef7a419c22..6c0f9c115b 100644 --- a/common/src/sync/packet.rs +++ b/common/src/sync/packet.rs @@ -23,18 +23,22 @@ pub trait CompPacket: Clone + Debug + Send + 'static { pub fn handle_insert(comp: C, entity: Entity, world: &World) { if let Err(err) = world.write_storage::().insert(entity, comp) { error!("Error inserting component: {:?}", err); - }; + } } /// Useful for implementing CompPacket trait pub fn handle_modify(comp: C, entity: Entity, world: &World) { - let _ = world + if world .write_storage::() .get_mut(entity) - .map(|c| *c = comp); + .map(|c| *c = comp) + .is_none() + { + error!("Error modifying synced component, it doesn't seem to exist"); + } } /// Useful for implementing CompPacket trait pub fn handle_remove(entity: Entity, world: &World) { - let _ = world.write_storage::().remove(entity); + world.write_storage::().remove(entity); } #[derive(Copy, Clone, Debug, Serialize, Deserialize)] @@ -81,12 +85,11 @@ impl StatePackage

{ } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SyncPackage { - pub comp_updates: Vec<(u64, CompUpdateKind

)>, +pub struct EntitySyncPackage { pub created_entities: Vec, pub deleted_entities: Vec, } -impl SyncPackage

{ +impl EntitySyncPackage { pub fn new<'a>( uids: &ReadStorage<'a, Uid>, uid_tracker: &UpdateTracker, @@ -100,11 +103,48 @@ impl SyncPackage

{ .collect(); Self { - comp_updates: Vec::new(), created_entities, deleted_entities, } } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CompSyncPackage { + // TODO: this can be made to take less space by clumping updates for the same entity together + pub comp_updates: Vec<(u64, CompUpdateKind

)>, +} + +impl CompSyncPackage

{ + pub fn new() -> Self { + Self { + comp_updates: Vec::new(), + } + } + + pub fn comp_inserted(&mut self, uid: Uid, comp: C) + where + P: From, + { + self.comp_updates + .push((uid.into(), CompUpdateKind::Inserted(comp.into()))); + } + + pub fn comp_modified(&mut self, uid: Uid, comp: C) + where + P: From, + { + self.comp_updates + .push((uid.into(), CompUpdateKind::Modified(comp.into()))); + } + + pub fn comp_removed(&mut self, uid: Uid) + where + P::Phantom: From>, + { + self.comp_updates + .push((uid.into(), CompUpdateKind::Removed(PhantomData::.into()))); + } pub fn with_component<'a, C: Component + Clone + Send + Sync>( mut self, diff --git a/common/src/sync/sync_ext.rs b/common/src/sync/sync_ext.rs index a84bdcb0b8..a8224b62a5 100644 --- a/common/src/sync/sync_ext.rs +++ b/common/src/sync/sync_ext.rs @@ -1,5 +1,7 @@ use super::{ - packet::{CompPacket, CompUpdateKind, EntityPackage, StatePackage, SyncPackage}, + packet::{ + CompPacket, CompSyncPackage, CompUpdateKind, EntityPackage, EntitySyncPackage, StatePackage, + }, track::UpdateTracker, uid::{Uid, UidAllocator}, }; @@ -27,7 +29,8 @@ pub trait WorldSyncExt { entity_package: EntityPackage

, ) -> specs::Entity; fn apply_state_package(&mut self, state_package: StatePackage

); - fn apply_sync_package(&mut self, package: SyncPackage

); + fn apply_entity_sync_package(&mut self, package: EntitySyncPackage); + fn apply_comp_sync_package(&mut self, package: CompSyncPackage

); } impl WorldSyncExt for specs::World { @@ -106,24 +109,30 @@ impl WorldSyncExt for specs::World { //self.maintain(); } - fn apply_sync_package(&mut self, package: SyncPackage

) { + fn apply_entity_sync_package(&mut self, package: EntitySyncPackage) { // Take ownership of the fields - let SyncPackage { - comp_updates, + let EntitySyncPackage { created_entities, deleted_entities, } = package; // Attempt to create entities - for entity_uid in created_entities { - create_entity_with_uid(self, entity_uid); - } + created_entities.into_iter().for_each(|uid| { + create_entity_with_uid(self, uid); + }); + // Attempt to delete entities that were marked for deletion + deleted_entities.into_iter().for_each(|uid| { + self.delete_entity_and_clear_from_uid_allocator(uid); + }); + } + + fn apply_comp_sync_package(&mut self, package: CompSyncPackage

) { // Update components - for (entity_uid, update) in comp_updates { + package.comp_updates.into_iter().for_each(|(uid, update)| { if let Some(entity) = self .read_resource::() - .retrieve_entity_internal(entity_uid) + .retrieve_entity_internal(uid) { match update { CompUpdateKind::Inserted(packet) => { @@ -137,12 +146,7 @@ impl WorldSyncExt for specs::World { }, } } - } - - // Attempt to delete entities that were marked for deletion - for entity_uid in deleted_entities { - self.delete_entity_and_clear_from_uid_allocator(entity_uid); - } + }); } } diff --git a/server/src/lib.rs b/server/src/lib.rs index 5d06f7498f..f4b2560393 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -468,7 +468,7 @@ impl Server { .notify(ServerMsg::InitialSync { // Send client their entity entity_package: TrackedComps::fetch(&self.state.ecs()) - .create_entity_package(entity), + .create_entity_package(entity, None, None, None), server_info: self.server_info.clone(), time_of_day: *self.state.ecs().read_resource(), world_map: (WORLD_SIZE.map(|e| e as u32), self.map.clone()), diff --git a/server/src/sys/entity_sync.rs b/server/src/sys/entity_sync.rs index f9a5dcfe19..d499a61ec4 100644 --- a/server/src/sys/entity_sync.rs +++ b/server/src/sys/entity_sync.rs @@ -11,7 +11,7 @@ use common::{ msg::ServerMsg, region::{Event as RegionEvent, RegionMap}, state::TimeOfDay, - sync::Uid, + sync::{CompSyncPackage, Uid}, }; use specs::{ Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage, System, Write, WriteStorage, @@ -30,13 +30,11 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Pos>, ReadStorage<'a, Vel>, ReadStorage<'a, Ori>, - ReadStorage<'a, CharacterState>, ReadStorage<'a, Inventory>, ReadStorage<'a, RegionSubscription>, WriteStorage<'a, Last>, WriteStorage<'a, Last>, WriteStorage<'a, Last>, - WriteStorage<'a, Last>, WriteStorage<'a, Client>, WriteStorage<'a, ForceUpdate>, WriteStorage<'a, InventoryUpdate>, @@ -57,13 +55,11 @@ impl<'a> System<'a> for Sys { positions, velocities, orientations, - character_states, inventories, subscriptions, mut last_pos, mut last_vel, mut last_ori, - mut last_character_state, mut clients, mut force_updates, mut inventory_updates, @@ -116,22 +112,18 @@ impl<'a> System<'a> for Sys { continue; } let entity = entities.entity(*id); - if let Some((uid, pos, vel, ori, character_state)) = - uids.get(entity).and_then(|uid| { - positions.get(entity).map(|pos| { - ( - uid, - pos, - velocities.get(entity), - orientations.get(entity), - character_states.get(entity), - ) - }) + if let Some((uid, pos, vel, ori)) = uids.get(entity).and_then(|uid| { + positions.get(entity).map(|pos| { + (uid, pos, velocities.get(entity), orientations.get(entity)) }) - { - let create_msg = ServerMsg::CreateEntity( - tracked_comps.create_entity_package(entity), - ); + }) { + let create_msg = + ServerMsg::CreateEntity(tracked_comps.create_entity_package( + entity, + Some(*pos), + vel.copied(), + ori.copied(), + )); for (client, regions, client_entity, _) in &mut subscribers { if maybe_key .as_ref() @@ -141,14 +133,6 @@ impl<'a> System<'a> for Sys { && *client_entity != entity { client.notify(create_msg.clone()); - send_initial_unsynced_components( - client, - uid, - pos, - vel, - ori, - character_state, - ); } } } @@ -172,18 +156,19 @@ impl<'a> System<'a> for Sys { // Sync tracked components // Get deleted entities in this region from DeletedEntities - let sync_msg = ServerMsg::EcsSync( - trackers.create_sync_package( - &tracked_comps, - region.entities(), - deleted_entities - .take_deleted_in_region(key) - .unwrap_or_else(|| Vec::new()), - ), + let (entity_sync_package, comp_sync_package) = trackers.create_sync_packages( + &tracked_comps, + region.entities(), + deleted_entities + .take_deleted_in_region(key) + .unwrap_or_else(|| Vec::new()), ); - for (client, _, _, _) in &mut subscribers { - client.notify(sync_msg.clone()); - } + let entity_sync_msg = ServerMsg::EntitySync(entity_sync_package); + let comp_sync_msg = ServerMsg::CompSync(comp_sync_package); + subscribers.iter_mut().for_each(move |(client, _, _, _)| { + client.notify(entity_sync_msg.clone()); + client.notify(comp_sync_msg.clone()); + }); let mut send_msg = |msg: ServerMsg, entity: EcsEntity, @@ -191,117 +176,112 @@ impl<'a> System<'a> for Sys { force_update: Option<&ForceUpdate>, throttle: bool| { for (client, _, client_entity, client_pos) in &mut subscribers { - let update = if client_entity == &entity { + if if client_entity == &entity { // Don't send client physics updates about itself unless force update is set force_update.is_some() } else if !throttle { - // Update rate not thottled by distance + // Send the message if not throttling true } else { // Throttle update rate based on distance to client let distance_sq = client_pos.0.distance_squared(pos.0); + let id_staggered_tick = tick + entity.id() as u64; // More entities farther away so checks start there if distance_sq > 300.0f32.powi(2) { - (tick + entity.id() as u64) % 32 == 0 + id_staggered_tick % 32 == 0 } else if distance_sq > 250.0f32.powi(2) { - (tick + entity.id() as u64) % 16 == 0 + id_staggered_tick % 16 == 0 } else if distance_sq > 200.0f32.powi(2) { - (tick + entity.id() as u64) % 8 == 0 + id_staggered_tick % 8 == 0 } else if distance_sq > 150.0f32.powi(2) { - (tick + entity.id() as u64) % 4 == 0 + id_staggered_tick % 4 == 0 } else if distance_sq > 100.0f32.powi(2) { - (tick + entity.id() as u64) % 2 == 0 + id_staggered_tick % 2 == 0 } else { true // Closer than 100 blocks } - }; - - if update { + } { client.notify(msg.clone()); } } }; // Sync physics components - for (_, entity, &uid, &pos, maybe_vel, maybe_ori, character_state, force_update) in ( + for (_, entity, &uid, &pos, maybe_vel, maybe_ori, force_update) in ( region.entities(), &entities, &uids, &positions, velocities.maybe(), orientations.maybe(), - character_states.maybe(), force_updates.maybe(), ) .join() { + let mut comp_sync_package = CompSyncPackage::new(); + let mut throttle = true; // TODO: An entity that stoppped moving on a tick that it wasn't sent to the // player will never have it's position updated - if last_pos.get(entity).map(|&l| l.0 != pos).unwrap_or(true) { - let _ = last_pos.insert(entity, Last(pos)); - send_msg( - ServerMsg::EntityPos { - entity: uid.into(), - pos, - }, - entity, - pos, - force_update, - true, - ); + match last_pos.get(entity).map(|&l| l.0 != pos) { + Some(false) => {}, + Some(true) => { + let _ = last_pos.insert(entity, Last(pos)); + comp_sync_package.comp_modified(uid, pos); + }, + None => { + let _ = last_pos.insert(entity, Last(pos)); + throttle = false; + comp_sync_package.comp_inserted(uid, pos); + }, } if let Some(&vel) = maybe_vel { - if last_vel.get(entity).map(|&l| l.0 != vel).unwrap_or(true) { - let _ = last_vel.insert(entity, Last(vel)); - send_msg( - ServerMsg::EntityVel { - entity: uid.into(), - vel, - }, - entity, - pos, - force_update, - true, - ); + match last_vel.get(entity).map(|&l| l.0 != vel) { + Some(false) => {}, + Some(true) => { + let _ = last_vel.insert(entity, Last(vel)); + comp_sync_package.comp_modified(uid, vel); + }, + None => { + let _ = last_vel.insert(entity, Last(vel)); + throttle = false; + comp_sync_package.comp_inserted(uid, vel); + }, } + } else if last_vel.remove(entity).is_some() { + // Send removal message if Vel was removed + // Note: we don't have to handle this for position because the entity will be + // removed from the client by the region system + throttle = false; + comp_sync_package.comp_removed::(uid); } if let Some(&ori) = maybe_ori { - if last_ori.get(entity).map(|&l| l.0 != ori).unwrap_or(true) { - let _ = last_ori.insert(entity, Last(ori)); - send_msg( - ServerMsg::EntityOri { - entity: uid.into(), - ori, - }, - entity, - pos, - force_update, - true, - ); + match last_ori.get(entity).map(|&l| l.0 != ori) { + Some(false) => {}, + Some(true) => { + let _ = last_ori.insert(entity, Last(ori)); + comp_sync_package.comp_modified(uid, ori); + }, + None => { + let _ = last_ori.insert(entity, Last(ori)); + throttle = false; + comp_sync_package.comp_inserted(uid, ori); + }, } + } else if last_ori.remove(entity).is_some() { + // Send removal message if Ori was removed + throttle = false; + comp_sync_package.comp_removed::(uid); } - if let Some(&character_state) = character_state.as_ref() { - if last_character_state - .get(entity) - .map(|l| !character_state.equals(&l.0)) - .unwrap_or(true) - { - let _ = last_character_state.insert(entity, Last(character_state.clone())); - send_msg( - ServerMsg::EntityCharacterState { - entity: uid.into(), - character_state: character_state.clone(), - }, - entity, - pos, - force_update, - false, - ); - } - } + send_msg( + ServerMsg::CompSync(comp_sync_package), + entity, + pos, + force_update, + throttle, + ); } } @@ -350,27 +330,3 @@ impl<'a> System<'a> for Sys { timer.end(); } } - -pub fn send_initial_unsynced_components( - client: &mut Client, - uid: &Uid, - pos: &Pos, - vel: Option<&Vel>, - ori: Option<&Ori>, - character_state: Option<&CharacterState>, -) { - let entity = (*uid).into(); - client.notify(ServerMsg::EntityPos { entity, pos: *pos }); - if let Some(&vel) = vel { - client.notify(ServerMsg::EntityVel { entity, vel }); - } - if let Some(&ori) = ori { - client.notify(ServerMsg::EntityOri { entity, ori }); - } - if let Some(character_state) = character_state.cloned() { - client.notify(ServerMsg::EntityCharacterState { - entity, - character_state, - }); - } -} diff --git a/server/src/sys/sentinel.rs b/server/src/sys/sentinel.rs index d9db6bbded..9b388e61cd 100644 --- a/server/src/sys/sentinel.rs +++ b/server/src/sys/sentinel.rs @@ -2,10 +2,10 @@ use super::SysTimer; use common::{ comp::{ Body, CanBuild, CharacterState, Energy, Gravity, Item, LightEmitter, Loadout, Mass, - MountState, Mounting, Player, Scale, Stats, Sticky, + MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel, }, msg::EcsCompPacket, - sync::{EntityPackage, SyncPackage, Uid, UpdateTracker, WorldSyncExt}, + sync::{CompSyncPackage, EntityPackage, EntitySyncPackage, Uid, UpdateTracker, WorldSyncExt}, }; use hashbrown::HashMap; use specs::{ @@ -55,7 +55,13 @@ pub struct TrackedComps<'a> { pub character_state: ReadStorage<'a, CharacterState>, } impl<'a> TrackedComps<'a> { - pub fn create_entity_package(&self, entity: EcsEntity) -> EntityPackage { + pub fn create_entity_package( + &self, + entity: EcsEntity, + pos: Option, + vel: Option, + ori: Option, + ) -> EntityPackage { let uid = self .uid .get(entity) @@ -114,6 +120,10 @@ impl<'a> TrackedComps<'a> { .get(entity) .cloned() .map(|c| comps.push(c.into())); + // Add untracked comps + pos.map(|c| comps.push(c.into())); + vel.map(|c| comps.push(c.into())); + ori.map(|c| comps.push(c.into())); EntityPackage { uid, comps } } @@ -138,13 +148,15 @@ pub struct ReadTrackers<'a> { pub character_state: ReadExpect<'a, UpdateTracker>, } impl<'a> ReadTrackers<'a> { - pub fn create_sync_package( + pub fn create_sync_packages( &self, comps: &TrackedComps, filter: impl Join + Copy, deleted_entities: Vec, - ) -> SyncPackage { - SyncPackage::new(&comps.uid, &self.uid, filter, deleted_entities) + ) -> (EntitySyncPackage, CompSyncPackage) { + let entity_sync_package = + EntitySyncPackage::new(&comps.uid, &self.uid, filter, deleted_entities); + let comp_sync_package = CompSyncPackage::new() .with_component(&comps.uid, &*self.body, &comps.body, filter) .with_component(&comps.uid, &*self.player, &comps.player, filter) .with_component(&comps.uid, &*self.stats, &comps.stats, filter) @@ -169,7 +181,9 @@ impl<'a> ReadTrackers<'a> { &*self.character_state, &comps.character_state, filter, - ) + ); + + (entity_sync_package, comp_sync_package) } } diff --git a/server/src/sys/subscription.rs b/server/src/sys/subscription.rs index f9de9609ba..07a8a15315 100644 --- a/server/src/sys/subscription.rs +++ b/server/src/sys/subscription.rs @@ -194,19 +194,16 @@ impl<'a> System<'a> for Sys { .join() .filter(|(_, _, _, _, _, _, e)| *e != client_entity) { - // Send message to create entity and tracked components + // Send message to create entity and tracked components and physics + // components client.notify(ServerMsg::CreateEntity( - tracked_comps.create_entity_package(entity), + tracked_comps.create_entity_package( + entity, + Some(*pos), + vel.copied(), + ori.copied(), + ), )); - // Send message to create physics components - super::entity_sync::send_initial_unsynced_components( - client, - uid, - pos, - vel, - ori, - character_state, - ); } } } @@ -253,19 +250,15 @@ pub fn initialize_region_subscription(world: &World, entity: specs::Entity) { ) .join() { - // Send message to create entity and tracked components + // Send message to create entity and tracked components and physics components client.notify(ServerMsg::CreateEntity( - tracked_comps.create_entity_package(entity), + tracked_comps.create_entity_package( + entity, + Some(*pos), + vel.copied(), + ori.copied(), + ), )); - // Send message to create physics components - super::entity_sync::send_initial_unsynced_components( - client, - uid, - pos, - vel, - ori, - character_state, - ); } } }