From c18ce37a4213ad6a4ffe999c3d0c2f870d0237c2 Mon Sep 17 00:00:00 2001 From: WiseDev <83840010+wisedevik@users.noreply.github.com> Date: Mon, 24 Aug 2026 20:13:16 +0300 Subject: [PATCH] gate the heartbeat off; it was resyncing the client every turn the live log showed the client requesting a full sector state every 500ms - one per turn, in lockstep with the heartbeat. the heartbeat verifies the client's predicted checksum against ours, and the sim is not yet bit-exact, so most turns mismatch, flip the client out of sync, and it re-downloads the whole state. that resync storm is the "86%, 70%..." loading flicker at battle start and it hard-resets the battle scene every turn, so nothing on screen can settle. the heartbeat now stays off unless SCROLL_HEARTBEAT=1. this returns the client to the snapshot-only path (a hard reset every 4 ticks, but no per-turn off-sync request). turn it back on once checksums reliably agree. --- crates/game-service/src/battle_session.rs | 8 +++++++- crates/game-service/tests/walk_to_tower.rs | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index fe5381b..5271a97 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; use std::sync::Arc; pub const SNAPSHOT_INTERVAL_TICKS: i32 = 4; +pub fn heartbeats_enabled() -> bool { + std::env::var("SCROLL_HEARTBEAT").map(|v| v == "1").unwrap_or(false) +} pub fn snapshot_interval_ticks() -> i32 { std::env::var("SCROLL_SNAPSHOT_INTERVAL_TICKS") .ok() @@ -265,7 +268,10 @@ impl BattleSession { } self.recent_checksums.push_back((self.tick, checksum)); } - if self.pushes_snapshots() && self.tick % TICKS_PER_TURN == 0 { + if heartbeats_enabled() + && self.pushes_snapshots() + && self.tick % TICKS_PER_TURN == 0 + { if let Some(checksum) = this_checksum { let turn = self.tick / TICKS_PER_TURN; if let Ok(message) = diff --git a/crates/game-service/tests/walk_to_tower.rs b/crates/game-service/tests/walk_to_tower.rs index f4e4aca..6433a07 100644 --- a/crates/game-service/tests/walk_to_tower.rs +++ b/crates/game-service/tests/walk_to_tower.rs @@ -495,9 +495,11 @@ fn the_session_emits_a_heartbeat_every_turn() { 1, ) .expect("battle"); + std::env::set_var("SCROLL_HEARTBEAT", "1"); let mut session = game_service::battle_session::BattleSession::new(mode, Vec::new()); session.advance_to(25); let out = session.take_outbound(); + std::env::remove_var("SCROLL_HEARTBEAT"); let heartbeats: Vec<&service_rpc::WireMessage> = out .iter() .filter(|m| m.message_type == 21902)