3.1 KiB
3.1 KiB
Prediction Scoring — Design Spec
Date: 2026-03-12 Status: Approved
Goal
Allow the host to enter actual ESC results, calculate prediction scores for all players, and display them on the leaderboard.
What Exists
- Players submit predictions (1st, 2nd, 3rd, last place) during lobby/pre-show via
PredictionsForm - Predictions lock when host advances to live-event act
GameManagerstores predictions in aMap<string, Prediction>- Leaderboard already shows jury (J:) and bingo (B:) points
- DB schema has
actual_winner,actual_second,actual_third,actual_lastcolumns onroomstable (nullable, set when host enters results)
New Functionality
1. Host Enters Actual Results
- New component:
ActualResultsForm— shown in the Host tab duringscoringandendedacts - Same country-picker UX as the predictions form (select from lineup, all 4 must be different)
- New WS message:
submit_actual_results(client → server) with{ winner, second, third, last } - Server stores on the
GameManager(in-memory) and broadcasts updated game state - Host can re-submit to correct mistakes (overwrites previous entry)
2. Server Scores Predictions
GameManager.setActualResults(winner, second, third, last)— stores the actual resultsGameManager.getPredictionScore(playerId)— compares player's prediction to actuals:firstmatcheswinner: 25 pts (scoring.prediction_winner)secondmatchessecond: 10 pts (scoring.prediction_top3)thirdmatchesthird: 10 pts (scoring.prediction_top3)lastmatcheslast: 15 pts (scoring.prediction_nul_points)- Total possible: 60 pts
- Prediction scores feed into
buildLeaderboardas a newpredictionPointsfield
3. Leaderboard Update
LeaderboardEntrygainspredictionPoints: number- Before results are entered: shows
P:?on the leaderboard - After results are entered: shows
P:<score>with actual points totalPointsincludes prediction points (0 if no results entered yet)
4. Player View — Results Reveal
- After actual results are entered, each player's
gameStateincludesactualResults: { winner, second, third, last } | null PredictionsForm(locked state) gains visual indicators: green checkmark for correct predictions, red X for incorrect- Players who didn't submit predictions get 0 prediction points
5. Display View
- Shows actual results summary when entered
- Shows leaderboard with prediction scores revealed
WS Messages
Client → Server:
| Type | Payload | Guard |
|---|---|---|
submit_actual_results |
winner, second, third, last (country codes) |
Host only, scoring or ended act |
No new server → client messages — the existing game_state broadcast carries all the data.
GameState Changes
// Added to GameState
actualResults: { winner: string; second: string; third: string; last: string } | null
// LeaderboardEntry gains
predictionPoints: number
Scoring Config Values (existing)
{
"prediction_winner": 25,
"prediction_top3": 10,
"prediction_nul_points": 15
}