Bug
backend/modules/chess/src/time_control.rs — PlayerClock::time_out() checks the raw remaining_time field, which is only decremented on stop():
pub fn time_out(&self) -> bool {
self.remaining_time.is_zero()
}
While a clock is_running, elapsed time is not reflected in remaining_time (it is applied later in stop()). So a player who sits on a running clock past zero is never reported as flagged. get_real_time_remaining() already accounts for the running clock:
pub fn get_real_time_remaining(&self) -> Duration {
if self.is_running {
if let Some(last_move_time) = self.last_move_time {
return self.remaining_time.saturating_sub(last_move_time.elapsed());
}
}
self.remaining_time
}
This is exactly the case flag-detection must catch: the player on the move letting their clock run out without moving. Game::check_time_out() (in game.rs) relies on time_out(), so it cannot detect that timeout.
Fix
pub fn time_out(&self) -> bool {
self.get_real_time_remaining().is_zero()
}
This does not break the existing test in tests/time_control_tests.rs (it asserts !time_out() on a stopped clock and time_out() after set_remaining_time(0) — both still hold).
Note (latent / related cleanup)
This is currently a latent defect: game.rs is not declared in chess/src/lib.rs (lib.rs only exposes bitboard, time_control, pgn, rating), so check_time_out() is uncompiled, and no live server code imports PlayerClock yet. But PlayerClock/time_out() are exported public API and will bite whoever wires up the clock. game.rs also mixes diesel while the rest of the crate uses sea_orm — possibly worth a separate cleanup issue.
Bug
backend/modules/chess/src/time_control.rs—PlayerClock::time_out()checks the rawremaining_timefield, which is only decremented onstop():While a clock
is_running, elapsed time is not reflected inremaining_time(it is applied later instop()). So a player who sits on a running clock past zero is never reported as flagged.get_real_time_remaining()already accounts for the running clock:This is exactly the case flag-detection must catch: the player on the move letting their clock run out without moving.
Game::check_time_out()(ingame.rs) relies ontime_out(), so it cannot detect that timeout.Fix
This does not break the existing test in
tests/time_control_tests.rs(it asserts!time_out()on a stopped clock andtime_out()afterset_remaining_time(0)— both still hold).Note (latent / related cleanup)
This is currently a latent defect:
game.rsis not declared inchess/src/lib.rs(lib.rsonly exposesbitboard, time_control, pgn, rating), socheck_time_out()is uncompiled, and no live server code importsPlayerClockyet. ButPlayerClock/time_out()are exported public API and will bite whoever wires up the clock.game.rsalso mixesdieselwhile the rest of the crate usessea_orm— possibly worth a separate cleanup issue.