How a rating change is calculated
This page is for readers who want to see the actual arithmetic. If you would rather skip the maths, the overview covers what you need to know as an operator.
ePegboard uses a standard Elo formulation adapted for doubles, with three small tweaks. The engine version tag in the database is elo-team-score-ratio-v1 if you want to grep for it. The whole formula is below; nothing is hidden.
The formula
Section titled “The formula”Each team’s rating is the average of its two players’ ratings:
team_rating = (player_one_rating + player_two_rating) / 2The expected share of points for your team against the opponent team is the standard Elo logistic:
expected_share = 1 / (1 + 10^((opponent_rating - team_rating) / 2200))Your actual share is your team’s score divided by the total points in the game:
actual_share = your_team_score / (your_team_score + opponent_score)Each of your team’s two players moves by:
rating_change = player_K × (actual_share - expected_share)The bracketed term (the team’s share-over-expected) is the same for both teammates. Each player’s K factor is their own, so a brand-new player paired with a settled player will move by a different number of points even though they are getting the same share of the team result.
The three tweaks vs textbook Elo
Section titled “The three tweaks vs textbook Elo”1. Wider spread constant (2200 vs the canonical 400)
Section titled “1. Wider spread constant (2200 vs the canonical 400)”Textbook Elo uses 400 in the denominator. ePegboard uses 2200, which means rating differences spread further before they swing the probability much. A 200-point gap puts the stronger team at roughly 56% favourite under our setting, vs about 75% under canonical Elo. This suits a club ladder where you want ratings to drift apart over a season and stay meaningful, rather than collapse around the middle.
2. Score ratio rather than binary win/loss
Section titled “2. Score ratio rather than binary win/loss”Textbook Elo treats every game as 1 (win) or 0 (loss). ePegboard uses the actual point split, so a 21-19 result is treated as 0.525 - 0.475 rather than 1.0 - 0.0. This means a close game moves ratings less than a walkover, and beating a stronger team convincingly moves you more than scraping past them. We think this matches what your eyes tell you on the night.
3. Decaying K factor
Section titled “3. Decaying K factor”The K factor controls how responsive a rating is to one game. New players need a high K (the system does not know them yet, so it should move fast); settled players need a low K (their rating already reflects their level, so single results should not move it much). ePegboard’s K factor starts at 500 and decreases by 10 per game, flooring at 30:
K = max(500 - (10 × rated_games_played), 30)| Rated games played | K factor | Why |
|---|---|---|
| 0 (first game) | 500 | New rating moves fast - the system does not know you yet. |
| 10 | 400 | Settling in. |
| 25 | 250 | Approaching your real level. |
| 47+ | 30 (floor) | Settled rating, moves slowly. One game at a time. |
K floors at 30 after 47 rated games, so even a long-established player keeps moving slightly per game - we do not freeze ratings entirely.
Worked examples
Section titled “Worked examples”Two evenly-matched teams, settled players
Section titled “Two evenly-matched teams, settled players”Four players, all rated around 1500, all with K=30. Team A wins 21-15.
- team_rating for both teams = 1500
- expected_share for Team A = 1 / (1 + 10^((1500 - 1500) / 2200)) = 0.500
- actual_share for Team A = 21 / 36 = 0.583
- rating_change for each Team A player = 30 × (0.583 - 0.500) = +2.5
- rating_change for each Team B player = -2.5
Same game, brand-new players
Section titled “Same game, brand-new players”Same scoreline, but all four players are on their first game (K=500).
- rating_change for each Team A player = 500 × 0.083 = +42
- rating_change for each Team B player = -42
Same scoreline, very different rating impact - because the system has more to learn about new players.
The underdog wins
Section titled “The underdog wins”Team A average 1500 vs Team B average 1700 (200-point gap). Team A wins 21-18.
- expected_share for Team A = 1 / (1 + 10^((1700 - 1500) / 2200)) = 0.448
- actual_share for Team A = 21 / 39 = 0.538
- rating_change for each Team A player (K=30) = 30 × (0.538 - 0.448) = +2.7
- rating_change for each Team B player (K=30) = -2.7
Notice the underdog gain is not dramatically higher than the evenly-matched case here - that is the wider spread constant at work. A 200-point gap is only a slight edge under our curve. If we had used textbook Elo’s 400-point spread, the upset would have been worth much more.
Why we picked these values
Section titled “Why we picked these values”The wider spread constant came out of running early club data: with C=400 ratings clustered tightly around the middle, because most games at a club night are between players within ~100 points of each other, and the curve was too aggressive for those small gaps. C=2200 lets the ladder fan out over a season without making every game an upset.
The decaying K factor came from wanting new players to settle quickly without making a single result life-changing for an established player. The 30 floor (rather than locking K at zero) means a settled rating still drifts in response to genuine form changes over time.
The score-ratio actual-share matches the operator intuition that “we only just won” should be different from “we hammered them”. Binary win/loss Elo treats those as identical, which felt wrong.
Notes and limits
Section titled “Notes and limits”- No per-player contribution weighting within a doubles game. The system does not know who hit the winning shot, so both teammates get the same share-of-team-result. Each player’s actual point change is then scaled by their own K factor, so mixed-K pairings (a new player with a settled one) see different point amounts. Over many games, players who consistently outperform their pairings drift up; players who consistently underperform drift down.
- A new player starts at 1500. If you set a different starting rating during member import or on the Members form, that overrides the 1500 default.
- Tied games are rejected: at least one team must score more than the other. A draw cannot update the formula meaningfully under this model, so the system will not accept the result.
- Games with both teams scoring zero are rejected for the same reason (the score-ratio is undefined).