Merge branch 'zesterer/network-tweaks' into 'master'

Zesterer/network tweaks

See merge request veloren/veloren!1913
This commit is contained in:
Joshua Barretto 2021-03-16 04:11:16 +00:00
commit fb850a4ec8
2 changed files with 65 additions and 118 deletions

View File

@ -5,7 +5,7 @@ use crate::{
Tick,
};
use common::{
comp::{ForceUpdate, Inventory, InventoryUpdate, Last, Ori, Pos, Vel},
comp::{Collider, ForceUpdate, Inventory, InventoryUpdate, Last, Ori, Pos, Vel},
outcome::Outcome,
region::{Event as RegionEvent, RegionMap},
resources::TimeOfDay,
@ -15,9 +15,7 @@ use common::{
};
use common_ecs::{Job, Origin, Phase, System};
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
use specs::{
Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage,
};
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
use vek::*;
/// This system will send physics updates to the client
@ -37,6 +35,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Inventory>,
ReadStorage<'a, RegionSubscription>,
ReadStorage<'a, Presence>,
ReadStorage<'a, Collider>,
WriteStorage<'a, Last<Pos>>,
WriteStorage<'a, Last<Vel>>,
WriteStorage<'a, Last<Ori>>,
@ -67,6 +66,7 @@ impl<'a> System<'a> for Sys {
inventories,
subscriptions,
presences,
colliders,
mut last_pos,
mut last_vel,
mut last_ori,
@ -199,133 +199,80 @@ impl<'a> System<'a> for Sys {
.map(|msg| client.send_prepared(&msg));
});
let mut send_general = |msg: ServerGeneral,
entity: EcsEntity,
pos: Pos,
force_update: Option<&ForceUpdate>,
throttle: bool| {
for (client, _, client_entity, client_pos) in &mut subscribers {
if if client_entity == &entity {
for (client, _, client_entity, client_pos) in &mut subscribers {
let mut comp_sync_package = CompSyncPackage::new();
for (_, entity, &uid, &pos, vel, ori, force_update, collider) in (
region.entities(),
&entities,
&uids,
&positions,
velocities.maybe(),
orientations.maybe(),
force_updates.maybe(),
colliders.maybe(),
)
.join()
{
// Decide how regularly to send physics updates.
let send_now = if client_entity == &entity {
// Don't send client physics updates about itself unless force update is set
force_update.is_some()
} else if !throttle {
// Send the message if not throttling
} else if matches!(collider, Some(Collider::Voxel { .. })) {
// Things with a voxel collider (airships, etc.) need to have very stable
// physics so we always send updated for these where
// we can.
true
} else {
// Throttle update rate based on distance to client
// Throttle update rates for all other entities 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) {
if distance_sq > 350.0f32.powi(2) {
id_staggered_tick % 64 == 0
} else if distance_sq > 180.0f32.powi(2) {
id_staggered_tick % 32 == 0
} else if distance_sq > 250.0f32.powi(2) {
id_staggered_tick % 16 == 0
} else if distance_sq > 200.0f32.powi(2) {
id_staggered_tick % 8 == 0
} else if distance_sq > 150.0f32.powi(2) {
id_staggered_tick % 4 == 0
} else if distance_sq > 100.0f32.powi(2) {
id_staggered_tick % 2 == 0
id_staggered_tick % 16 == 0
} else if distance_sq > 48.0f32.powi(2) {
id_staggered_tick % 8 == 0
} else if distance_sq > 24.0f32.powi(2) {
id_staggered_tick % 4 == 0
} else {
true // Closer than 100 blocks
id_staggered_tick % 3 == 0
}
} {
client.send_fallible(msg.clone());
};
if send_now {
if last_pos.get(entity).is_none() {
comp_sync_package.comp_inserted(uid, pos);
let _ = last_pos.insert(entity, Last(pos));
} else {
comp_sync_package.comp_modified(uid, pos);
}
vel.map(|v| {
if last_vel.get(entity).is_none() {
comp_sync_package.comp_inserted(uid, *v);
let _ = last_vel.insert(entity, Last(*v));
} else {
comp_sync_package.comp_modified(uid, *v);
}
});
ori.map(|o| {
if last_ori.get(entity).is_none() {
comp_sync_package.comp_inserted(uid, *o);
let _ = last_ori.insert(entity, Last(*o));
} else {
comp_sync_package.comp_modified(uid, *o);
}
});
}
}
};
// Sync physics components
for (_, entity, &uid, &pos, maybe_vel, maybe_ori, force_update) in (
region.entities(),
&entities,
&uids,
&positions,
velocities.maybe(),
orientations.maybe(),
force_updates.maybe(),
)
.join()
{
let mut comp_sync_package = CompSyncPackage::new();
let mut throttle = true;
// Extrapolation depends on receiving several frames indicating that something
// has stopped in order for the extrapolated value to have
// stopped
const SEND_UNCHANGED_PHYSICS_DATA: bool = true;
// TODO: An entity that stopped moving on a tick that it wasn't sent to the
// player will never have its position updated
match last_pos
.get(entity)
.map(|&l| l.0 != pos || SEND_UNCHANGED_PHYSICS_DATA)
{
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 {
match last_vel
.get(entity)
.map(|&l| l.0 != vel || SEND_UNCHANGED_PHYSICS_DATA)
{
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::<Vel>(uid);
}
if let Some(&ori) = maybe_ori {
match last_ori
.get(entity)
.map(|&l| l.0 != ori || SEND_UNCHANGED_PHYSICS_DATA)
{
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::<Ori>(uid);
}
send_general(
ServerGeneral::CompSync(comp_sync_package),
entity,
pos,
force_update,
throttle,
);
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
}
}

View File

@ -635,7 +635,7 @@ impl FigureMgr {
// goes further and further away, we start to 'skip' update ticks.
// TODO: Investigate passing the velocity into the shader so we can at least
// interpolate motion
const MIN_PERFECT_RATE_DIST: f32 = 50.0;
const MIN_PERFECT_RATE_DIST: f32 = 100.0;
if (i as u64 + tick)
% (1 + ((pos.0.distance_squared(focus_pos).powf(0.25)