Match loop on the client side: orders go to the server, a confirmed turn steps the world five times, and a checksum of the shared state catches worlds that diverge

This commit is contained in:
Richard Zink committed 2026-11-04 11:07:24 +01:00
1 parent 87890adc53
commit 42034b062b
7 files changed
+303 -10

No files matched your search

+15 -6
View File
@@ -594,6 +594,8 @@ pub struct Game {
#[serde(skip)]
step_acc: f32, // real time not yet paid for with a step
#[serde(skip)]
pub netplay: Option<crate::netplay::Netplay>, // a match: turns come in, the world steps per turn
#[serde(skip)]
pub hints: bool, // show hint messages (setting)
#[serde(skip, default = "hint_times")]
hint_t: [f32; 32], // last time each hint slot was shown
@@ -774,6 +776,7 @@ impl Game {
cmd_seq: 0,
sim_steps: 0,
step_acc: 0.0,
netplay: None,
hint_t: hint_times(),
reserve: 0.0,
incoming: Vec::new(),
@@ -1176,13 +1179,19 @@ impl Game {
// ---------------------------------------------------------------- update
pub fn update(&mut self, dt: f32) {
self.step_acc = (self.step_acc + dt).min(STEP * MAX_STEPS_PER_FRAME as f32);
let mut steps = 0usize;
while self.step_acc >= STEP {
self.step_acc -= STEP;
steps += 1;
}
let cmds = std::mem::take(&mut self.pending);
let cmds = if self.netplay.is_some() {
// a match runs turn by turn (see netplay.rs): without the next turn the world stands still,
// and local orders are not applied here - they travel to the server first
Vec::new()
} else {
self.step_acc = (self.step_acc + dt).min(STEP * MAX_STEPS_PER_FRAME as f32);
while self.step_acc >= STEP {
self.step_acc -= STEP;
steps += 1;
}
std::mem::take(&mut self.pending)
};
self.apply_turn(&cmds, steps);
// what only the camera cares about runs in real time: it is not part of the shared state
self.update_particles(dt);