From bc04651a73f5dea9490302ec990ad21c15f4a92b Mon Sep 17 00:00:00 2001 From: WiseDev <83840010+wisedevik@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:09:27 +0300 Subject: [PATCH] write the compression flag byte in SectorStateMessage SectorManager::receiveSectorState reads one byte off the front of the message body and branches on it: 1 goes to receiveCompressedSectorState, anything else falls through to the plain decode. we never wrote that byte, so the client ate the first byte of the snapshot as the flag and then read every field one byte early - server tick 0, discard 11, and the section sentinel landed on the LogicTime tick instead of 11. drop the two bisect switches, they served their purpose: both settings aborted identically, which is what ruled out the object payload. --- crates/game-service/src/battle.rs | 19 ++----------------- crates/logic/src/messages/sector_state.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/crates/game-service/src/battle.rs b/crates/game-service/src/battle.rs index c1f8c09..fedaae9 100644 --- a/crates/game-service/src/battle.rs +++ b/crates/game-service/src/battle.rs @@ -24,14 +24,6 @@ pub struct TowerSpec { pub struct BattleBuilder { root: PathBuf, buff_type_count: usize, - summoner_bodies: bool, - princess_towers: bool, -} -fn env_flag(key: &str) -> bool { - !matches!( - std::env::var(key).unwrap_or_default().as_str(), - "0" | "false" | "off" - ) } fn tile_to_units(tile: i32) -> i32 { tile.saturating_mul(SUBTILE_UNITS) @@ -55,11 +47,6 @@ impl BattleBuilder { .unwrap_or(0); tracing::info!( buff_type_count, - summoner_bodies = env_flag("SCROLL_BATTLE_SUMMONER"), - princess_towers = env_flag("SCROLL_BATTLE_PRINCESS"), - damage_types = LogicDataTables::instance().table(table::DAMAGE_TYPES).map(|t| t.count()).unwrap_or(0), - character_buffs = LogicDataTables::instance().table(table::CHARACTER_BUFFS).map(|t| t.count()).unwrap_or(0), - king = %character_data(CHARACTER_KING_TOWER), king_id = ?character_data(CHARACTER_KING_TOWER).global_id(), princess_id = ?character_data(CHARACTER_PRINCESS_TOWER).global_id(), "battle builder ready" @@ -67,8 +54,6 @@ impl BattleBuilder { Self { root: root.as_ref().to_path_buf(), buff_type_count, - summoner_bodies: env_flag("SCROLL_BATTLE_SUMMONER"), - princess_towers: env_flag("SCROLL_BATTLE_PRINCESS"), } } pub fn buff_type_count(&self) -> usize { @@ -172,13 +157,13 @@ impl BattleBuilder { owner: owner as i32, level_index: 0, is_leader: true, - summoner: self.summoner_bodies, + summoner: true, }); leaders[owner] = entry.global_id; objects.push(entry); instance += 1; } - if !princess.is_none() && self.princess_towers { + if !princess.is_none() { for tile in tilemap.princess_towers() { let owner = usize::from(tile_to_units(tile.1) >= middle); let entry = self.tower(TowerSpec { diff --git a/crates/logic/src/messages/sector_state.rs b/crates/logic/src/messages/sector_state.rs index 6be4070..f111923 100644 --- a/crates/logic/src/messages/sector_state.rs +++ b/crates/logic/src/messages/sector_state.rs @@ -1,12 +1,16 @@ use titan::Message; +pub const SECTOR_STATE_UNCOMPRESSED: u8 = 0; #[derive(Debug, Default, Clone, PartialEq, Eq, Message)] #[message(id = 21903, direction = "server", name = "SectorStateMessage")] #[codec(raw)] pub struct SectorStateMessage { - pub snapshot: Vec, + pub body: Vec, } impl SectorStateMessage { pub fn new(snapshot: Vec) -> Self { - Self { snapshot } + let mut body = Vec::with_capacity(snapshot.len() + 1); + body.push(SECTOR_STATE_UNCOMPRESSED); + body.extend_from_slice(&snapshot); + Self { body } } }