fix(simulation): use non-blocking TCP to prevent game loop stall
read_framed() called read_exact() which blocked the entire bevy Update schedule waiting for client input — no systems ran until a keystroke arrived. Switch TcpStream to non-blocking mode so receive_inputs() returns Ok(vec![]) on WouldBlock instead of blocking. Toggle to blocking for snapshot writes (reliable delivery). Add 50ms frame throttle (~20 ticks/sec) since the non-blocking loop would otherwise spin. Downgrade input receive logging to trace, add error logging for missing bridge resource and failed observer queries. Fixes bug #1 (server never sends snapshots) and #2 (camera doesn't center until first keystroke). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+12
-2
@@ -226,13 +226,23 @@ fn main() {
|
||||
|
||||
tracing::info!("Simulation initialized, entering game loop");
|
||||
|
||||
// Game loop: run until client disconnects
|
||||
// Game loop: run until client disconnects.
|
||||
// Targets ~20 ticks/sec (2 game-minutes/sec). The TCP bridge uses
|
||||
// non-blocking reads, so without throttling this loop would spin.
|
||||
// Remaining frame budget is available for NPC AI and pathfinding.
|
||||
let target_frame_time = std::time::Duration::from_millis(50);
|
||||
loop {
|
||||
let frame_start = std::time::Instant::now();
|
||||
|
||||
app.update();
|
||||
// Check ServerRunning resource
|
||||
if !app.world().resource::<ServerRunning>().0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let elapsed = frame_start.elapsed();
|
||||
if elapsed < target_frame_time {
|
||||
std::thread::sleep(target_frame_time - elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
tracing::info!("Simulation server shutting down");
|
||||
|
||||
Reference in New Issue
Block a user