From 97b7f8d968bdcc95fc5ea22ce1ca8655a961f5b0 Mon Sep 17 00:00:00 2001 From: WiseDev <83840010+wisedevik@users.noreply.github.com> Date: Sun, 23 Aug 2026 16:52:47 +0300 Subject: [PATCH] drop the renumbering, it never earned its keep the princess towers do not draw either, red or blue, so what is on screen is arena scenery and no object in the battle has ever had a model. that makes the failure uniform rather than per character, and it kills the last reason to hand objects new ids: renumbering was only ever there to make them new again, it did not help, and it destroys and rebuilds objects the hud holds pointers into. what is verified and can stop being re-examined: LogicGameObject::decode reads owner at +48, the component mask at +0x4c, the position at +52 and z at +0x44, in that order, which is what we write. LogicCharacter's two booleans are the destroyed flag at +208 and isLeader at +209, both rightly false for a troop. LogicGameMode::decode reuses the existing battle rather than rebuilding it, so the listener survives. and the checksum agreeing byte for byte says every field we write lands where the client expects it. --- crates/game-service/src/battle_session.rs | 29 +---------------------- crates/game-service/src/service.rs | 2 +- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index 4e11cee..b8f6d09 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -11,8 +11,7 @@ pub fn snapshot_interval_ticks() -> i32 { pub const MAX_CATCH_UP_TICKS: i32 = 40; use std::time::Instant; use logic::battle::{ - LogicGameMode, LogicGameObjectEntry, LogicGameObjectRef, LogicVector2, - BATTLE_TICKS_PER_SECOND, BATTLE_TYPE_PVP, CHARACTER_OBJECT_TYPE, + LogicGameMode, LogicGameObjectEntry, LogicVector2, BATTLE_TICKS_PER_SECOND, BATTLE_TYPE_PVP, }; use logic::battle::{verify_snapshot, LogicBattleEvent}; use logic::SectorStateMessage; @@ -66,37 +65,11 @@ impl BattleSession { pending_bot_play: None, } } - fn reannounce(&mut self) { - let leaders = self.mode.battle.leaders; - let mut remap: Vec<(LogicGameObjectRef, LogicGameObjectRef)> = Vec::new(); - for entry in self.mode.battle.objects.objects.iter_mut() { - if leaders.contains(&entry.global_id) { - continue; - } - let fresh = LogicGameObjectRef::of(CHARACTER_OBJECT_TYPE + 1, self.next_instance); - self.next_instance += 1; - remap.push((entry.global_id, fresh)); - entry.global_id = fresh; - } - for towers in self.mode.battle.leader_towers.iter_mut() { - for tower in towers.iter_mut() { - if let Some((_, now)) = remap.iter().find(|(was, _)| was == tower) { - *tower = *now; - } - } - } - self.mode - .battle - .objects - .objects - .sort_by_key(|entry| entry.global_id.0.map(|id| (id.class_id, id.instance_id))); - } pub fn announce(&mut self) -> bool { if self.announced { return false; } self.announced = true; - self.reannounce(); self.next_snapshot = self.tick; true } diff --git a/crates/game-service/src/service.rs b/crates/game-service/src/service.rs index 17a373c..7a55724 100644 --- a/crates/game-service/src/service.rs +++ b/crates/game-service/src/service.rs @@ -161,7 +161,7 @@ impl GameService { opponent = %opponent_name, location = %location, objects, - "sending the opening sector state, objects get new ids once the client is up" + "sending the opening sector state" ); Ok(vec![message]) }