Skip to content

feat: Add Local Timer#151

Open
cjs8487 wants to merge 16 commits intomainfrom
timer
Open

feat: Add Local Timer#151
cjs8487 wants to merge 16 commits intomainfrom
timer

Conversation

@cjs8487
Copy link
Owner

@cjs8487 cjs8487 commented Dec 20, 2025

Adds a local timer option to rooms, which is always active, regardless of if a game is opted in to the racetime.gg beta. This additionally further fleshes out the RaceHandler interface, and in turn adds additional functionality to the racetime interface as well.

New Features

  • Adds a local timing option to rooms
    • The timing method can be changed by room monitor from the room controls dialog
    • The local timer times games entirely locally within PlayBingo, using relatively simple timing logic (storing start and end times and calculating the differences)
      • Local timing has no support for (and likely never get support for) advanced racing functionality, such as streaming requirements, countdowns, more precise timing with the server, and ranking. Games should continue to choose racetime if they need any of this functionality
      • Local timing is intended for solo play and casual races, not particularly for competitive play, though it is reasonably accurate and precise enough that it could be used if racetime is not an option for some reason
  • New general RaceHandler features:
    • Return the start and end time of a race discretely
    • Start/reset the timer for the entire room
      • Unavailable for racetime due to player websocket limitations. Reseting is also impossible in racetime completely
    • Tracking when individual players finish, and when all players finish
      • For local timing, this sets local data and serializes it, and for racetime it will dispatch websocket events. All players finishing is a no-op for racetime, as it is handled on the racetime side of the integration

Changes

  • Improved the behavior of rooms when being reinitialized with racetime data. Rooms that had previously been connected to racetime should now correctly remember their original room upon reinitialization

Bug Fixes

  • Fixed a bug that caused the fractional portion of seconds to display incorrectly in the timer due to a math error

Technical Notes

The code in this PR is still a bit messy. Over time, the room class has become a bit of a catchall and has largely become overgrown and bloated. The original racetime integration was designed specifically for racetime, with no regard for potentially adding other systems. A basic interface was extracted on top of it as a a first step in refactoring, but that was only a half measure, and didn't make many of the needed changes to the room class itself (in fact the object in the room itself was still typed as a RacetimeHandler). This PR gets, probably 75% of the way to having RaceHandlers be completely interchangeable, however, there is still a large dependence on some racetime specific design elements that needs to be refactored. I think this PR has already scope creeped enough, and that refactor should stand on its own, since it also begs some non-trivial questions about when information clients need about races and how that should be structured.

This also slightly refactors how RaceHandler works with the player data structure, leveraging the full structure instead of some arbitrary identifier within the the player that the player must pass in. This ultimately decouples the player structure from services such as the racetime auth token service, moving that responsibility into the implementation of the relevant race handler.

Another major divergence in this PR is that all race related actions included in this PR occur over websocket and only websocket. Previously, racetime actions had to be performed over http due to websocket authentication limitations, which have since been overcome. However, no work has been done to bring the /actions framework in line with the websocket implementation. This isn't particularly an issue, but something worth noting. I think ultimately this leads to an interesting refactor opportunity with rooms - if we can make the websocket message into a generic message type that we validate (such as with zod) based on the action, we can share core handling logic between websocket and http., but that is way beyond the scope of discussion for this PR.

@Floha258 Floha258 self-requested a review February 4, 2026 18:19
Copy link
Collaborator

@Floha258 Floha258 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got some minor suggestions

@cjs8487 cjs8487 requested a review from Floha258 February 6, 2026 01:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants