From c98a4f7a58c2f2f945ef7801ab4dd9711bd54d6c Mon Sep 17 00:00:00 2001 From: Ludovic Marie <136255825+ludovic111@users.noreply.github.com> Date: Sat, 17 Oct 2026 11:07:14 +0200 Subject: [PATCH] Server advancements: flushDirty skips players whose progress didn't change PlayerAdvancements.flushDirty only works when it is the first packet or progress changed. Horizon walked the whole advancement tree for every network player every tick to find nothing new: a fifth of the server tick with 50 players. Co-Authored-By: Claude Opus 5.5 --- crates/horizon-client/src/lan/advancements.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/horizon-client/src/lan/advancements.rs b/crates/horizon-client/src/lan/advancements.rs index 0e0caf7ff..e0b8ad450 100644 --- a/crates/horizon-client/src/lan/advancements.rs +++ b/crates/horizon-client/src/lan/advancements.rs @@ -144,6 +144,13 @@ impl ServerAdvancements { ) -> Option> { let n = self.tree.list.len(); let first = visible.len() != n; + // flushDirty does nothing unless it is the first packet or progress + // changed: visibility follows progress alone, and every grant and + // revoke is in `changed`. This skips walking the whole tree for + // every player every tick. + if !first && changed.is_empty() { + return None; + } let now = self .tree .visible(&self.kids, |i| progress.done(&self.tree.list[i]));