← Leaderboard
A plain-English guide

How ratings work.

A guide to what those numbers actually mean — no math degree required.

§ 01 What the rating represents
⚡
Chess-style Elo · TrueSkill team math

Ratings move chess-Elo style: a fixed K-factor per match, boosted by score margin, damped to keep the league stable. The team aggregation — how four players' ratings combine into "team strength" and how credit gets split after a doubles match — comes from TrueSkill, Microsoft Research's algorithm used in Xbox Halo and DOTA-style ladders.

We started purely on TrueSkill, then layered on margin-of-victory weighting, monthly era resets, and a constant K-factor so the league behaves like a chess club: predictable rating movement, long-term standings that mean something.

Every player on the leaderboard has one number next to their name — like 1500, 2400, or 3100. That number is the system's best guess at how strong the player is right now.

The Tier Ladder
3000+
Dominating

League's apex. Current ceiling around 3100.

2500
Top of the league

Consistent winner. Beats most opponents most of the time.

2000
Solid intermediate

Can hang with most of the league. Match outcomes go either way.

1500
Brand new

Default starting rating. The system has no data on you yet.

The scale is loosely modeled on chess Elo, where most rated club players live between 1200 and 2400. We extended it slightly for badminton because doubles tends to produce higher numbers than chess.

§ 02 How wins and losses move your rating

After every match, every player's rating moves up or down. Two rules:

  1. You win → rating goes up. You lose → rating goes down. Obviously.
  2. The amount depends on who you played. Beating a player rated way above you gives you a lot. Beating someone way below you barely moves the needle. Same in reverse: losing to someone weaker hurts more than losing to someone stronger.

This is what stops the system from being gamed. You can't pad your rating by playing only weaker opponents — those wins are worth almost nothing. You also don't get punished for taking on tougher opponents and losing.

"If you want to climb fast, beat someone you 'shouldn't' beat. That's where the points are."

§ 03 Why the score matters (the "margin")

A 35-34 nailbiter and a 35-0 blowout aren't the same thing — and the system reads them differently:

Close win
35 – 34

Suggests the teams are roughly even.
Small rating change.

Blowout
35 – 0

Suggests the winners are clearly better.
Bigger rating change.

The bigger the gap, the more the system updates. But it's capped — there's no super-bonus for 35-0 specifically. After about a 20-point margin the effect levels off, so a blowout and a destruction count similarly.

§ 04 Monthly resets & eras

About once a month the league gets a rating reset. Whatever spread the regulars had accumulated — top of the league at 3500, bottom at 1900 — gets proportionally squished into the 1500–2500 band. The top stays the top, the bottom stays the bottom, but everyone starts the new era closer together.

Each squished era is called a season. The History tab keeps a full archive — for any past season, you can see the leaderboard exactly as it stood the moment of the reset.

Why resets? Without them, a few players who got hot early pull away from the league and never come back — and the algorithm becomes more confident over time that the gap is real, so the ratings stabilize but stop telling a fresh story. The monthly reset re-tightens the field so every season has competitive stakes: anyone can climb 500 points or fall 500 in a month and it matters.

Non-regulars (guests, one-night visitors) don't get the proportional squish — anyone below the regulars' floor just lands on 1500. That keeps the regulars' band from getting compressed by a single crushed visitor's rating leaking into the bounds.

§ 05 What a single match actually moves

One match changes your rating by roughly:

  • ±15-30 for an expected outcome (top beats bottom)
  • ±40-90 for a balanced match
  • ±100-260 for a genuine upset (underdog beats favorite)

The biggest single-match swing possible (a bottom-of-league team blowing out the top by 35-0) tops out around 300 display points. Five losses in one night drops you somewhere around 200-400 — meaningful, recoverable in a couple of strong sessions. The K-factor is the knob that controls this; it can be tuned tighter or looser if the league wants more or less volatility.

§ 06 Why TrueSkill's team math — but not its dynamics

Classic chess Elo is built for two individuals facing each other. Badminton doubles is two teams of two, and the system needs to know how to:

  • Combine two partners' ratings into a "team strength"
  • Split credit between teammates when they win or lose
  • Account for the fact that a strong partner can carry a weaker one

TrueSkill — Microsoft Research, 2007, same algorithm that powers Xbox Halo matchmaking — solves this natively via Bayesian factor graphs. That's the half of the system we kept.

What we replaced was the dynamics. Vanilla TrueSkill tracks confidence as a Bayesian uncertainty band: rating moves shrink as a player accumulates more games. For a small league with monthly resets, that pushes ratings toward early stability and late staleness — players get "locked in" and matches stop mattering in their final standings.

So we pin uncertainty flat across the league (σ = 6), apply a fixed K-factor (K = 0.33) to scale every update, and reset the whole field once a month. The result feels more like a chess club than a competitive ladder: predictable movement, every match contributes, the leaderboard tells you this month's story.

§ 07 Under the hood (for the curious)

The actual math, in the current era:

  • Every player is modeled as a normal distribution N(μ, σ²). Post-reset σ is pinned at 6.0 for everyone, so μ alone moves.
  • The displayed rating is (μ − 3σ) × 60 + 1500. With σ flat, this collapses to a linear function of μ, which is why we can do the proportional reset squish cleanly.
  • After every match we feed the four ratings into the TrueSkill team posterior (factor-graph message passing — that's the part we keep from TrueSkill). We then scale the μ update by K · margin_weight, where K = 0.33 and margin_weight = 1 + 0.5 · ln(1 + (winner − loser) / winner), capped at 1.6×. A 35-34 nailbiter weight ~1.01×; a 35-0 demolition ~1.35×.
  • Era boundaries are explicit events in the timeline. A reset on date D takes each regular's rating, computes a target via new = 1500 + (old − pre_min) / (pre_max − pre_min) · 1000 (where pre_min/pre_max are the regulars' range), and writes a new rating_history row pinned to that target. Non-regulars below the regulars' floor land on 1500. Matches after the reset evolve from these new values.
  • Win probability uses the standard TrueSkill formula Φ(Δμ / √(N·β² + Σσ²)), temperature-calibrated by dividing the z-score by 4.8 before the CDF — raw predictions were too confident on small-league data.

Roughly 2,500 lines of Python. TrueSkill via the trueskill library for the team math; the K-factor / flat-σ / reset / margin layers are this project's. Everything is deterministic: given the matches table and these constants, running recompute_all reproduces the same final ratings every time.

§ 08 Common questions
Q: Can I see all of my matches?

Yes. Click your name from the leaderboard. The "Match Log" section shows every game you've ever played, with the ELO change for each — plus a gold ◆ marker on every era boundary so you can tell which season each match belongs to.

Q: I had a great month last season and my rating got reset. Why?

The reset isn't about you — it's about the league. Whatever rank you held going into the reset is preserved (#1 stays #1, #15 stays #15), the absolute numbers just get rescaled. The History tab shows the final pre-reset leaderboard for every past season, so your big month is on the record forever.

Q: Why does the leaderboard show "★ PR" next to so many players?

That chip means a player is currently at their lifetime peak rating. Right after a reset most regulars sit near their reset value, which counts as a peak. Over the season the chip will appear and disappear as players climb past or fall below their previous best.

Q: My partner and I beat a team rated much higher. Why did we only gain a few points?

Margin: a 35-34 squeaker is worth less than a 35-22 statement, and K = 0.33 dampens everything to keep the league stable. A genuine upset still earns 100-260 points, just not 400+. If you win three upsets in a session you'll feel it in your standing.

Q: Is this still TrueSkill?

Half. We use TrueSkill's team math — how four players' ratings combine into team strength and how credit splits after a match. We don't use its Bayesian confidence-tracking anymore (σ is pinned flat, K-factor scales every update uniformly). The honest description is "chess-style Elo with TrueSkill team aggregation."

Q: Why was the homepage hero about someone who didn't even play this week?

It shouldn't be. If you spot one, that's a bug — the system filters for players who actually played in the latest session. Let Jetson Ngo know.

Built by Jetson Ngo · this page itself was generated from the live source code, so it's always in sync with how the system actually works.