mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
optimize des more
This commit is contained in:
parent
3dcd6b4ec8
commit
bf71bde27f
4 changed files with 105 additions and 71 deletions
|
@ -12,8 +12,8 @@ use interest::InterestTracker;
|
||||||
use noita_api::raw::game_get_frame_num;
|
use noita_api::raw::game_get_frame_num;
|
||||||
use noita_api::serialize::serialize_entity;
|
use noita_api::serialize::serialize_entity;
|
||||||
use noita_api::{
|
use noita_api::{
|
||||||
DamageModelComponent, EntityID, LuaComponent, PositionSeedComponent, ProjectileComponent,
|
DamageModelComponent, EntityID, ItemCostComponent, LuaComponent, PositionSeedComponent,
|
||||||
VariableStorageComponent,
|
ProjectileComponent, VariableStorageComponent,
|
||||||
};
|
};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use shared::des::DesToProxy::UpdatePositions;
|
use shared::des::DesToProxy::UpdatePositions;
|
||||||
|
@ -55,15 +55,14 @@ pub(crate) struct EntitySync {
|
||||||
delta_sync_rate: usize,
|
delta_sync_rate: usize,
|
||||||
kill_later: Vec<(EntityID, Option<PeerId>)>,
|
kill_later: Vec<(EntityID, Option<PeerId>)>,
|
||||||
timer: u128,
|
timer: u128,
|
||||||
|
to_track: Vec<EntityID>,
|
||||||
}
|
}
|
||||||
impl EntitySync {
|
impl EntitySync {
|
||||||
/*pub(crate) fn has_gid(&self, gid: Gid) -> bool {
|
/*pub(crate) fn has_gid(&self, gid: Gid) -> bool {
|
||||||
self.local_diff_model.has_gid(gid) || self.remote_models.values().any(|r| r.has_gid(gid))
|
self.local_diff_model.has_gid(gid) || self.remote_models.values().any(|r| r.has_gid(gid))
|
||||||
}*/
|
}*/
|
||||||
pub(crate) fn track_entity(&mut self, ent: EntityID) {
|
pub(crate) fn track_entity(&mut self, ent: EntityID) {
|
||||||
let _ = self
|
let _ = self.local_diff_model.track_and_upload_entity(ent);
|
||||||
.local_diff_model
|
|
||||||
.track_and_upload_entity(ent, Gid(rand::random()));
|
|
||||||
}
|
}
|
||||||
pub(crate) fn notrack_entity(&mut self, ent: EntityID) {
|
pub(crate) fn notrack_entity(&mut self, ent: EntityID) {
|
||||||
self.dont_track.insert(ent);
|
self.dont_track.insert(ent);
|
||||||
|
@ -101,6 +100,7 @@ impl Default for EntitySync {
|
||||||
delta_sync_rate: 0,
|
delta_sync_rate: 0,
|
||||||
kill_later: Vec::new(),
|
kill_later: Vec::new(),
|
||||||
timer: 0,
|
timer: 0,
|
||||||
|
to_track: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,8 +413,7 @@ impl EntitySync {
|
||||||
let entity = entity.ok_or_eyre("Passed entity 0 into cross call")?;
|
let entity = entity.ok_or_eyre("Passed entity 0 into cross call")?;
|
||||||
// It might be already tracked in case of tablet telekinesis, no need to track it again.
|
// It might be already tracked in case of tablet telekinesis, no need to track it again.
|
||||||
if !self.local_diff_model.is_entity_tracked(entity) {
|
if !self.local_diff_model.is_entity_tracked(entity) {
|
||||||
self.local_diff_model
|
self.local_diff_model.track_and_upload_entity(entity)?;
|
||||||
.track_and_upload_entity(entity, Gid(rand::random()))?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -495,8 +494,13 @@ impl Module for EntitySync {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if self.should_be_tracked(entity)? {
|
if self.should_be_tracked(entity)? {
|
||||||
let gid = Gid(rand::random());
|
if let Some(cost) = entity.try_get_first_component::<ItemCostComponent>(None)? {
|
||||||
self.local_diff_model.track_and_upload_entity(entity, gid)?;
|
if cost.stealable()? {
|
||||||
|
cost.set_stealable(false)?;
|
||||||
|
entity.get_var_or_default("ew_was_stealable")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.to_track.push(entity);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -535,12 +539,19 @@ impl Module for EntitySync {
|
||||||
self.look_current_entity = EntityID::max_in_use()?;
|
self.look_current_entity = EntityID::max_in_use()?;
|
||||||
self.local_diff_model.enable_later()?;
|
self.local_diff_model.enable_later()?;
|
||||||
self.local_diff_model.phys_later()?;
|
self.local_diff_model.phys_later()?;
|
||||||
self.local_diff_model.update_pending_authority()?;
|
let t = self.local_diff_model.update_pending_authority()?;
|
||||||
for ent in self.look_current_entity.0.get() + 1..=EntityID::max_in_use()?.0.get() {
|
for ent in self.look_current_entity.0.get() + 1..=EntityID::max_in_use()?.0.get() {
|
||||||
if let Ok(ent) = EntityID::try_from(ent) {
|
if let Ok(ent) = EntityID::try_from(ent) {
|
||||||
self.on_new_entity(ent, false)?;
|
self.on_new_entity(ent, false)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
while let Some(entity) = self.to_track.pop() {
|
||||||
|
self.local_diff_model.track_and_upload_entity(entity)?;
|
||||||
|
if start.elapsed().as_micros() + t > 2000 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
let tmr = std::time::Instant::now();
|
let tmr = std::time::Instant::now();
|
||||||
{
|
{
|
||||||
let (diff, dead) = self
|
let (diff, dead) = self
|
||||||
|
@ -554,63 +565,63 @@ impl Module for EntitySync {
|
||||||
let new_intersects = self.interest_tracker.got_any_new_interested();
|
let new_intersects = self.interest_tracker.got_any_new_interested();
|
||||||
if !new_intersects.is_empty() {
|
if !new_intersects.is_empty() {
|
||||||
let init = self.local_diff_model.make_init();
|
let init = self.local_diff_model.make_init();
|
||||||
for peer in &new_intersects {
|
send_remotedes(
|
||||||
send_remotedes(
|
ctx,
|
||||||
ctx,
|
true,
|
||||||
true,
|
Destination::Peers(new_intersects.clone()),
|
||||||
Destination::Peer(*peer),
|
RemoteDes::EntityUpdate(init),
|
||||||
RemoteDes::EntityUpdate(init.clone()),
|
)?;
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// FIXME (perf): allow a Destination that can send to several peers at once, to prevent cloning and stuff.
|
let proj = std::mem::take(&mut self.pending_fired_projectiles);
|
||||||
for peer in self.interest_tracker.iter_interested() {
|
if !proj.is_empty() {
|
||||||
if !self.pending_fired_projectiles.is_empty() {
|
send_remotedes(
|
||||||
send_remotedes(
|
ctx,
|
||||||
ctx,
|
true,
|
||||||
true,
|
Destination::Peers(self.interest_tracker.iter_interested().collect()),
|
||||||
Destination::Peer(peer),
|
RemoteDes::Projectiles(proj),
|
||||||
RemoteDes::Projectiles(self.pending_fired_projectiles.clone()),
|
)?;
|
||||||
)?;
|
|
||||||
}
|
|
||||||
if new_intersects.contains(&peer) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if !diff.is_empty() {
|
|
||||||
send_remotedes(
|
|
||||||
ctx,
|
|
||||||
true,
|
|
||||||
Destination::Peer(peer),
|
|
||||||
RemoteDes::EntityUpdate(diff.clone()),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for peer in ctx.player_map.clone().left_values() {
|
if !diff.is_empty() {
|
||||||
if !self.interest_tracker.contains(*peer)
|
send_remotedes(
|
||||||
&& *peer != my_peer_id()
|
ctx,
|
||||||
&& !dead.is_empty()
|
true,
|
||||||
{
|
Destination::Peers(
|
||||||
send_remotedes(
|
self.interest_tracker
|
||||||
ctx,
|
.iter_interested()
|
||||||
true,
|
.filter(|p| !new_intersects.contains(p))
|
||||||
Destination::Peer(*peer),
|
.collect(),
|
||||||
RemoteDes::DeadEntities(dead.clone()),
|
),
|
||||||
)?;
|
RemoteDes::EntityUpdate(diff),
|
||||||
}
|
)?;
|
||||||
|
}
|
||||||
|
if !dead.is_empty() {
|
||||||
|
send_remotedes(
|
||||||
|
ctx,
|
||||||
|
true,
|
||||||
|
Destination::Peers(
|
||||||
|
ctx.player_map
|
||||||
|
.left_values()
|
||||||
|
.filter(|p| {
|
||||||
|
!self.interest_tracker.contains(**p)
|
||||||
|
&& **p != my_peer_id()
|
||||||
|
&& !dead.is_empty()
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
RemoteDes::DeadEntities(dead),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Arc::make_mut(&mut self.pending_fired_projectiles).clear();
|
|
||||||
if frame_num.saturating_sub(self.delta_sync_rate) % self.real_sync_rate
|
if frame_num.saturating_sub(self.delta_sync_rate) % self.real_sync_rate
|
||||||
== self.real_sync_rate - 1
|
== self.real_sync_rate - 1
|
||||||
{
|
{
|
||||||
let lids = self.local_diff_model.get_lids();
|
let lids = self.local_diff_model.get_lids();
|
||||||
for peer in self.interest_tracker.iter_interested() {
|
send_remotedes(
|
||||||
send_remotedes(
|
ctx,
|
||||||
ctx,
|
true,
|
||||||
true,
|
Destination::Peers(self.interest_tracker.iter_interested().collect()),
|
||||||
Destination::Peer(peer),
|
RemoteDes::AllEntities(lids),
|
||||||
RemoteDes::AllEntities(lids.clone()),
|
)?;
|
||||||
)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if frame_num > 120 {
|
if frame_num > 120 {
|
||||||
|
@ -675,7 +686,7 @@ impl Module for EntitySync {
|
||||||
}
|
}
|
||||||
|
|
||||||
let ms = tmr.elapsed().as_micros();
|
let ms = tmr.elapsed().as_micros();
|
||||||
self.timer += ms;
|
self.timer += ms + start.elapsed().as_micros() + t;
|
||||||
if frame_num.saturating_sub(self.delta_sync_rate) % self.real_sync_rate
|
if frame_num.saturating_sub(self.delta_sync_rate) % self.real_sync_rate
|
||||||
== self.real_sync_rate - 1
|
== self.real_sync_rate - 1
|
||||||
{
|
{
|
||||||
|
|
|
@ -597,7 +597,7 @@ impl LocalDiffModelTracker {
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
if let Some(cost) = entity.try_get_first_component::<ItemCostComponent>(None)? {
|
if let Some(cost) = entity.try_get_first_component::<ItemCostComponent>(None)? {
|
||||||
let (cx, cy) = noita_api::raw::game_get_camera_pos()?;
|
let (cx, cy) = noita_api::raw::game_get_camera_pos()?;
|
||||||
if (cx as f32 - x).powi(2) + (cy as f32 - y).powi(2) < 512.0 * 512.0 {
|
if (cx as f32 - x).powi(2) + (cy as f32 - y).powi(2) < 256.0 * 256.0 {
|
||||||
cost.set_stealable(true)?;
|
cost.set_stealable(true)?;
|
||||||
entity.remove_component(*var)?;
|
entity.remove_component(*var)?;
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ impl LocalDiffModelTracker {
|
||||||
vel.set_air_friction(0.55)?;
|
vel.set_air_friction(0.55)?;
|
||||||
}
|
}
|
||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
var.set_value_int(16)?;
|
var.set_value_int(32)?;
|
||||||
if let Some(vel) = entity.try_get_first_component::<VelocityComponent>(None)? {
|
if let Some(vel) = entity.try_get_first_component::<VelocityComponent>(None)? {
|
||||||
vel.set_gravity_y(0.0)?;
|
vel.set_gravity_y(0.0)?;
|
||||||
vel.set_air_friction(10.0)?;
|
vel.set_air_friction(10.0)?;
|
||||||
|
@ -912,11 +912,8 @@ impl LocalDiffModel {
|
||||||
Ok(lid)
|
Ok(lid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn track_and_upload_entity(
|
pub(crate) fn track_and_upload_entity(&mut self, entity: EntityID) -> eyre::Result<()> {
|
||||||
&mut self,
|
let gid = Gid(rand::random());
|
||||||
entity: EntityID,
|
|
||||||
gid: Gid,
|
|
||||||
) -> eyre::Result<()> {
|
|
||||||
let lid = self.track_entity(entity, gid)?;
|
let lid = self.track_entity(entity, gid)?;
|
||||||
self.upload.insert(lid);
|
self.upload.insert(lid);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -964,7 +961,7 @@ impl LocalDiffModel {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_pending_authority(&mut self) -> eyre::Result<()> {
|
pub(crate) fn update_pending_authority(&mut self) -> eyre::Result<u128> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
while let Some(entity_data) = self.tracker.pending_authority.pop() {
|
while let Some(entity_data) = self.tracker.pending_authority.pop() {
|
||||||
let entity = spawn_entity_by_data(
|
let entity = spawn_entity_by_data(
|
||||||
|
@ -1033,11 +1030,11 @@ impl LocalDiffModel {
|
||||||
self.dont_upload.insert(lid);
|
self.dont_upload.insert(lid);
|
||||||
|
|
||||||
// Don't handle too much in one frame to avoid stutters.
|
// Don't handle too much in one frame to avoid stutters.
|
||||||
if start.elapsed().as_millis() > 2 {
|
if start.elapsed().as_micros() > 2000 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(start.elapsed().as_micros())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
|
|
|
@ -881,6 +881,11 @@ impl NetManager {
|
||||||
fn do_message_request(&self, request: impl Into<MessageRequest<NetMsg>>) {
|
fn do_message_request(&self, request: impl Into<MessageRequest<NetMsg>>) {
|
||||||
let request: MessageRequest<NetMsg> = request.into();
|
let request: MessageRequest<NetMsg> = request.into();
|
||||||
match request.dst {
|
match request.dst {
|
||||||
|
Destination::Peers(peers) => {
|
||||||
|
for peer in peers {
|
||||||
|
self.send(peer, &request.msg, request.reliability);
|
||||||
|
}
|
||||||
|
}
|
||||||
Destination::Peer(peer) => {
|
Destination::Peer(peer) => {
|
||||||
self.send(peer, &request.msg, request.reliability);
|
self.send(peer, &request.msg, request.reliability);
|
||||||
}
|
}
|
||||||
|
@ -1128,6 +1133,21 @@ impl NetManager {
|
||||||
let destination = destination.convert::<OmniPeerId>();
|
let destination = destination.convert::<OmniPeerId>();
|
||||||
let reliability = Reliability::from_reliability_bool(reliable);
|
let reliability = Reliability::from_reliability_bool(reliable);
|
||||||
match destination {
|
match destination {
|
||||||
|
Destination::Peers(peers) => {
|
||||||
|
if !peers.is_empty() {
|
||||||
|
if peers.len() == 1 {
|
||||||
|
self.send(peers[0], &NetMsg::RemoteMsg(message), reliability)
|
||||||
|
} else {
|
||||||
|
for peer in peers {
|
||||||
|
self.send(
|
||||||
|
peer,
|
||||||
|
&NetMsg::RemoteMsg(message.clone()),
|
||||||
|
reliability,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Destination::Peer(peer) => {
|
Destination::Peer(peer) => {
|
||||||
self.send(peer, &NetMsg::RemoteMsg(message), reliability)
|
self.send(peer, &NetMsg::RemoteMsg(message), reliability)
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ impl PeerId {
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq)]
|
#[derive(Encode, Decode, Debug, PartialEq, Eq)]
|
||||||
pub enum Destination<PeerType> {
|
pub enum Destination<PeerType> {
|
||||||
|
Peers(Vec<PeerType>),
|
||||||
Peer(PeerType),
|
Peer(PeerType),
|
||||||
Host,
|
Host,
|
||||||
Broadcast,
|
Broadcast,
|
||||||
|
@ -113,9 +114,14 @@ impl<T> Destination<T> {
|
||||||
pub fn convert<A>(self) -> Destination<A>
|
pub fn convert<A>(self) -> Destination<A>
|
||||||
where
|
where
|
||||||
A: From<T>,
|
A: From<T>,
|
||||||
|
T: Copy,
|
||||||
|
T: Clone,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Destination::Peer(p) => Destination::Peer(p.into()),
|
Destination::Peer(p) => Destination::Peer(p.into()),
|
||||||
|
Destination::Peers(p) => {
|
||||||
|
Destination::Peers(p.iter().cloned().map(|p| p.into()).collect())
|
||||||
|
}
|
||||||
Destination::Host => Destination::Host,
|
Destination::Host => Destination::Host,
|
||||||
Destination::Broadcast => Destination::Broadcast,
|
Destination::Broadcast => Destination::Broadcast,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue