Fix confetti firing for non-unanimous votes (#16)#17
Open
martijn wants to merge 2 commits into
Open
Conversation
Confetti celebrated whenever the non-pending votes that had arrived so far all matched. Because votes and the "show votes" signal are delivered independently over SignalR, a client could process the reveal before a differing vote (e.g. someone voting 1) arrived, see an apparently unanimous set, and fire confetti for a round that was not unanimous. Only celebrate once the round is fully settled: every player must have cast the same numeric vote. A pending vote (not voted yet, or still in transit) now blocks the celebration, so a late differing vote can no longer trigger a false positive. The check is re-evaluated on every render while votes are shown, so a unanimous result that settles just after the reveal still celebrates. Extracted the logic into a testable GameState.IsUnanimous extension and added unit tests covering the reported scenario.
Make the celebration decision authoritative instead of letting each client re-evaluate against its own, possibly incomplete, state: - The player who reveals the votes computes unanimity (which they can do reliably since they have the full picture) and the result rides along on the VotesShown event as a ShowConfetti flag. Every client simply honours that flag, so confetti can no longer fire on one client for a round that was not unanimous. - VoteCast events are now dropped once votes have been shown, so a late or post-reveal vote can't change a locked round. IsUnanimous goes back to ignoring abstentions (no vote / Coffee / Question): with the decision made once by the revealer there is no race to guard against, so abstaining no longer suppresses the celebration. Added GameAggregate tests for dropping post-reveal votes and for the ShowConfetti flag, and updated the unanimity tests accordingly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #16.
The bug
Confetti celebrated whenever the votes that had arrived on a client so far happened to match. Because votes and the "show votes" signal are delivered independently over SignalR, a client could process the reveal before a differing vote (e.g. someone voting
1) arrived, briefly see an apparently unanimous set, and fire confetti for a round that was not unanimous.The fix
Decide the celebration once, authoritatively, at reveal time.
VotesShownevent as aShowConfettiflag.Lock the round after reveal.
VoteCastevents are dropped once votes have been shown, so a late or post-reveal vote can no longer alter a locked round.GameResetclearsShowConfettiso the next round starts clean.Unanimity ignores abstentions.
GameState.IsUnanimous()returns true when more than one player cast a numeric vote and all such votes match. Players who abstained — did not vote (Pending) or picked a non-numeric option (☕️/❓) — are ignored. So2,2,2,1,(abstain)→ no confetti, while2,2,2,(abstain)→ confetti.Tests
GameStateExtensionsTests— unanimity, the reported2,2,2,1,abstainedcase, abstentions ignored, all-abstain, single player.GameAggregateTests— post-reveal votes dropped,ShowConfettipropagation, reset clears it.https://claude.ai/code/session_01Di2fXRK9wbnM52f9QJDay9