Changelog - Version 5.7.9 (2026-05-21)
Version Information
- Updated version from 5.7.8 to 5.7.9
- Fix for the Stable bot: subathon timer now auto-ends, no longer loses time on pause/resume, and the overlay countdown no longer drifts
Bug Fixes
- Fixed subathon timer never auto-ending when time ran out
- The
subathon_countdownbackground task had abreakstatement placed outside the end-time check, so the loop exited after a single iteration regardless of whether the subathon had actually finished. - The task is now scoped correctly: it only breaks when the subathon has reached its end time (and gets paused + the chat message announced), or when no active subathon exists. While the subathon is still running, the task re-checks every 30 seconds.
- Without this fix, a subathon’s database row stayed
paused = Falsepastend_timeindefinitely until a moderator manually ran!subathon stop.
- The
- Fixed up-to-59-seconds being lost every time a subathon was paused
pause_subathonwas flooring the remaining time with// 60, so any sub-minute remainder at the moment of pause was silently discarded. A subathon paused at 1h 23m 47s would resume at 1h 23m 0s.- The bot now stores the precise remaining time in seconds (new
remaining_secondscolumn on thesubathontable) and uses it on resume.
- Fixed subathon overlay drifting and only displaying whole minutes
- The overlay was ticking with
setInterval(60000)and decrementing a local minute counter, which drifts under browser/OBS browser-source throttling and only ever showed0 second(s)regardless of true remaining time. - The bot now sends an absolute
end_timestamp_ms(Unix milliseconds) in theSUBATHON_START,SUBATHON_RESUME, andSUBATHON_ADD_TIMEwebsocket payloads, so the overlay can tick against a fixed target and display real seconds.
- The overlay was ticking with
Technical Details
subathon_countdown(): moved thebreakstatement inside the end-time conditional, added an explicit early break for paused/missing subathon state, and reduced the poll interval from 60 seconds to 30 seconds so the auto-end announcement fires closer to the true end time. The auto-end path now also emits aSUBATHON_STOPwebsocket notice so overlays react.pause_subathon(): dropped the// 60floor. Computesremaining_secondsdirectly fromtotal_seconds(), stores it to the newremaining_secondscolumn, and includes it in theSUBATHON_PAUSEwebsocket payload alongside the legacyremaining_minutesfield.resume_subathon(): readsremaining_secondsfrom the database when available, falls back toremaining_minutes * 60for any row that paused before the column existed, and computesend_time = now + timedelta(seconds=stored_seconds). TheSUBATHON_RESUMEwebsocket payload now includesend_timestamp_ms.start_subathon()andaddtime_subathon(): websocket payloads now includeend_timestamp_ms(Unix milliseconds) so the overlay can tick against an absolute target.- Schema migration: a new
remaining_seconds INT NOT NULL DEFAULT 0column was added to thesubathontable via the existing column-diff migration logic inusr_database.php.
Thank you for your feedback and support!
As always, your feedback is appreciated. Please report any issues, bugs, or suggestions in the #ticket-info channel on our Discord server. You can also submit feedback and bug reports directly on our support website: https://support.botofthespecter.com/