From 8bf73f89d4aa89cb4f16617a2201c4e8f497a7d5 Mon Sep 17 00:00:00 2001 From: Ludovic Marie <136255825+ludovic111@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:20:26 +0200 Subject: [PATCH] Locator bar: look up each connection and its two players once A moving player updates its connection with every other player, three times a tick (updateWaypoint, then updatePlayer at the position change and at ServerChunkCache.move), so with 40 players there are about 4800 updates a tick. Each looked the connection up twice and both players up four to six times. Now an update finds the connection's place once and resolves the two players once, then checks, updates or remakes it there. The same packets go out, in the same order. Co-Authored-By: Claude Opus 5.5 --- crates/horizon-client/src/lan/waypoints.rs | 96 ++++++++++------------ 1 file changed, 42 insertions(+), 54 deletions(-) diff --git a/crates/horizon-client/src/lan/waypoints.rs b/crates/horizon-client/src/lan/waypoints.rs index e3067871c..852cfc4fb 100644 --- a/crates/horizon-client/src/lan/waypoints.rs +++ b/crates/horizon-client/src/lan/waypoints.rs @@ -160,7 +160,7 @@ struct Tick<'a> { out: Vec<(u32, C)>, } -impl Tick<'_> { +impl<'a> Tick<'a> { fn send( &mut self, receiver: u128, @@ -172,16 +172,8 @@ impl Tick<'_> { let Some(conn) = self.players.get(&receiver).and_then(|p| p.conn) else { return; }; - self.out.push(( - conn, - C::TrackedWaypoint(TrackedWaypoint { - operation, - id: WaypointId::Uuid(source), - style: icon.style.clone(), - color: icon.color, - target, - }), - )); + self.out + .push((conn, waypoint(source, operation, icon, target))); } fn connect(&mut self, receiver: u128, source: u128, c: &Connection) { let target = match c.kind { @@ -230,11 +222,13 @@ impl Tick<'_> { let d = [0, 1, 2].map(|k| receiver.position[k] - source.position[k]); horizon_core::geometry::trig::atan2(d[0], -d[2]) as f32 } + /// The source and the receiver, if both are in the level this tick. + fn pair(&self, source: u128, receiver: u128) -> Option<(&'a Player, &'a Player)> { + Some((*self.players.get(&source)?, *self.players.get(&receiver)?)) + } /// `LivingEntity.makeWaypointConnectionWith`. - fn make(&self, source: u128, receiver: u128) -> Option { - let (s, r) = (self.players.get(&source)?, self.players.get(&receiver)?); - if s.first_tick || self.fresh.contains(&source) || source == receiver || self.ignores(s, r) - { + fn make(&self, (s, r): (&Player, &Player)) -> Option { + if s.first_tick || self.fresh.contains(&s.uuid) || s.uuid == r.uuid || self.ignores(s, r) { return None; } // Waypoint.Icon.cloneAndAssignStyle: the icon's colour, else the team's. @@ -244,7 +238,7 @@ impl Tick<'_> { } let kind = if Self::really_far(s, r) { Kind::Azimuth(Self::azimuth(s, r)) - } else if !self.chunk_visible(s.chunk(), receiver) { + } else if !self.chunk_visible(s.chunk(), r.uuid) { Kind::Chunk(s.chunk()) } else { Kind::Block(s.block()) @@ -252,10 +246,8 @@ impl Tick<'_> { Some(Connection { kind, icon }) } /// `Connection.isBroken` for each kind. - fn broken(&self, c: &Connection, source: u128, receiver: u128) -> bool { - let (Some(s), Some(r)) = (self.players.get(&source), self.players.get(&receiver)) else { - return true; - }; + fn broken(&self, c: &Connection, (s, r): (&Player, &Player)) -> bool { + let receiver = r.uuid; match c.kind { Kind::Block(last) => { let now = s.block(); @@ -274,10 +266,7 @@ impl Tick<'_> { } } /// `Connection.update`: the packet when the waypoint moved. - fn update(&mut self, c: &mut Connection, source: u128, receiver: u128) { - let (Some(s), Some(r)) = (self.players.get(&source), self.players.get(&receiver)) else { - return; - }; + fn update(&mut self, c: &mut Connection, (s, r): (&Player, &Player)) { let target = match &mut c.kind { Kind::Block(last) => { let now = s.block(); @@ -304,24 +293,26 @@ impl Tick<'_> { WaypointTarget::Azimuth(now) } }; - self.send( - receiver, - source, - waypoint_operation::UPDATE, - &c.icon, - target, - ); + if let Some(conn) = r.conn { + self.out.push(( + conn, + waypoint(s.uuid, waypoint_operation::UPDATE, &c.icon, target), + )); + } } } +fn waypoint(source: u128, operation: i32, icon: &Icon, target: WaypointTarget) -> C { + C::TrackedWaypoint(TrackedWaypoint { + operation, + id: WaypointId::Uuid(source), + style: icon.style.clone(), + color: icon.color, + target, + }) +} + impl Waypoints { - fn connection(&mut self, receiver: u128, source: u128) -> Option<&mut Connection> { - self.connections - .get_mut(&receiver)? - .iter_mut() - .find(|(s, _)| *s == source) - .map(|(_, c)| c) - } fn put(&mut self, receiver: u128, source: u128, c: Connection) { let row = self.connections.entry(receiver).or_default(); match row.iter_mut().find(|(s, _)| *s == source) { @@ -340,7 +331,7 @@ impl Waypoints { if receiver == source || !t.enabled { return; } - match t.make(source, receiver) { + match t.pair(source, receiver).and_then(|pair| t.make(pair)) { Some(c) => { t.connect(receiver, source, &c); self.put(receiver, source, c); @@ -352,23 +343,28 @@ impl Waypoints { } } } - /// `updateConnection`, on the connection in its place. - fn update_connection(&mut self, t: &mut Tick, receiver: u128, source: u128) { + /// The receiver's connection to the source updated in its place + /// (`updateConnection`), or made if it has none (`createConnection`). + fn update_or_create(&mut self, t: &mut Tick, receiver: u128, source: u128) { if receiver == source || !t.enabled { return; } let Some(row) = self.connections.get_mut(&receiver) else { - return; + return self.create_connection(t, receiver, source); }; let Some(i) = row.iter().position(|(s, _)| *s == source) else { - return; + return self.create_connection(t, receiver, source); }; let c = &mut row[i].1; - if !t.broken(c, source, receiver) { - t.update(c, source, receiver); + // A connection to a player who isn't in the level is broken. + let pair = t.pair(source, receiver); + if let Some(pair) = pair + && !t.broken(c, pair) + { + t.update(c, pair); return; } - match t.make(source, receiver) { + match pair.and_then(|pair| t.make(pair)) { Some(new) => { t.connect(receiver, source, &new); *c = new; @@ -379,14 +375,6 @@ impl Waypoints { } } } - /// The receiver's connection to the source updated, or made if it has none. - fn update_or_create(&mut self, t: &mut Tick, receiver: u128, source: u128) { - if self.connection(receiver, source).is_some() { - self.update_connection(t, receiver, source); - } else { - self.create_connection(t, receiver, source); - } - } /// `trackWaypoint`. fn track(&mut self, t: &mut Tick, source: u128) { if !self.waypoints.contains(&source) {