From f51d76f7800825a65ce16cf8f863eec972903105 Mon Sep 17 00:00:00 2001 From: WiseDev <83840010+wisedevik@users.noreply.github.com> Date: Sun, 23 Aug 2026 13:58:48 +0300 Subject: [PATCH] stamp the tick on the snapshot that carries it the snapshot is built inside the tick loop but the clock was written after it, so every pushed state went out carrying the tick from the previous call. LogicGameMode::decode compares that number against the last one it saw and ignores anything older, so a stale stamp is the difference between a state being applied and being dropped on the floor. the clock advances with the tick now. the sector command log gains the summoner mana, how many snapshots have gone out, and the type of the command that arrived, so the next run says whether the push is happening at all rather than leaving it to inference. --- crates/game-service/src/battle_session.rs | 21 ++++++++++++++++++++- crates/game-service/src/service.rs | 3 +++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index 030bdff..09c2d34 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -22,6 +22,7 @@ pub struct BattleSession { next_bot_emote: i32, next_snapshot: i32, next_bot_play: i32, + pub pushed_snapshots: u32, pending_bot_play: Option<(LogicDataRef, LogicVector2, i32)>, } impl BattleSession { @@ -39,6 +40,7 @@ impl BattleSession { next_bot_emote, next_snapshot: SNAPSHOT_INTERVAL_TICKS, next_bot_play: 0, + pushed_snapshots: 0, pending_bot_play: None, } } @@ -88,6 +90,18 @@ impl BattleSession { pub fn pushes_snapshots(&self) -> bool { self.mode.battle.battle_type == BATTLE_TYPE_PVP } + pub fn mana(&self) -> Option { + self.mode.battle.objects.objects.iter().find_map(|entry| { + match &entry.body { + logic::battle::LogicObjectBody::Summoner(summoner) + if entry.owner_index() == 0 => + { + Some(summoner.mana) + } + _ => None, + } + }) + } fn snapshot_message(&mut self) -> Option { let snapshot = self.mode.snapshot().ok()?; let report = verify_snapshot(&snapshot); @@ -162,11 +176,13 @@ impl BattleSession { pub fn advance_to(&mut self, tick: i32) { while self.tick < tick { self.tick += 1; + self.mode.time.tick = self.tick; self.release_queued(self.tick); self.mode.battle.tick(self.tick); if self.pushes_snapshots() && self.tick >= self.next_snapshot { self.next_snapshot = self.tick + SNAPSHOT_INTERVAL_TICKS; if let Some(message) = self.snapshot_message() { + self.pushed_snapshots += 1; self.outbound.push(message); } } @@ -187,7 +203,6 @@ impl BattleSession { } } } - self.mode.time.tick = self.tick; } fn release_queued(&mut self, tick: i32) { let mut due = Vec::new(); @@ -323,6 +338,8 @@ impl BattleRegistry { objects: session.object_count(), towers: session.towers_standing(), checksum: session.checksum(), + mana: session.mana(), + pushed: session.pushed_snapshots, }) } pub async fn play( @@ -361,4 +378,6 @@ pub struct BattleProgress { pub objects: usize, pub towers: (usize, usize), pub checksum: Option, + pub mana: Option, + pub pushed: u32, } diff --git a/crates/game-service/src/service.rs b/crates/game-service/src/service.rs index 5a56cc6..b5468e8 100644 --- a/crates/game-service/src/service.rs +++ b/crates/game-service/src/service.rs @@ -512,9 +512,12 @@ impl GameApi for GameService { server_checksum, agrees = server_checksum == Some(sector.client_checksum), objects = progress.map(|state| state.objects), + mana = progress.and_then(|state| state.mana), + pushed = progress.map(|state| state.pushed), towers = ?progress.map(|state| state.towers), stars = ?progress.map(|state| state.stars), spawned, + command = sector.command.as_ref().map(|command| command.command_type()), "sector command" ); Ok(())