How rating works
A skill rating for Tendril players. The exact formula, every setting, and the tiers, in plain words.
What it is
Your rating is a number that says how well your programs do against other players. It starts at 1200, goes up when you finish above where the field expects you to, and goes down when you finish below. It only reads final ranks on the leaderboard, so a score is never changed by it. Every run is still checked by the server, which replays the moves.
The system is Elo adapted for many players at once, the same family Codeforces uses. It was chosen over a percentile score for one reason: beating a weak account is worth almost nothing, so fake accounts cannot lift anyone.
There are three ratings, one for each medal: Overall (best net worth), Speed (reached par soonest) and Brevity (fewest tokens). Your headline rating is Overall. Each one is worked out separately from that medal’s board.
What gets rated
- Every daily, and the weekly season when it closes on Monday. A season counts 1.5 times a daily. Duels and Endless are never rated.
- A contest is rated after it closes and its late submissions have settled, so the number can appear a little after the board closes.
- Only your best entry on the board stands for you that day. A run below par keeps your streak and leaves your rating alone.
- Your GitHub account must be at least 14 days old when the contest closes. One rating per GitHub account.
- The entry must be declared as written by a human, must not be an identical log or the same program as an earlier player’s, and must have reached par.
- Declared model runs have their own lane: they are shown as ghosts on the models board and never move a human’s rating.
- If fewer than 8 players qualify in a discipline, that contest is left unrated.
What this cannot do: it cannot tell whether a person or a model wrote an undeclared program. No site can. The rating measures what your program did.
The maths
For every rated contest, take each rated player’s best entry on the board, in board order. Ties share the average of their places.
Chance of beating. For two ratings, the chance that A finishes above B is the standard Elo curve:
P(A beats B) = 1 / (1 + 10 ^ ((R_B - R_A) / 400))
Expected place. Your expected place is 1 plus the sum, over every other player in the field, of their chance of beating you.
E = 1 + sum over other players B of P(B beats you)
Performance. Take the geometric mean of your expected place and your actual place. Your performance rating is the rating at which that place would have been expected, found by binary search between 0 and 4000.
target = sqrt(E x actual place)
performance = the rating whose expected place equals the target
Change. Your rating moves 1/2 of the way toward your performance, then is scaled by three weights and capped.
change = (performance - rating) / 2 x placement x field-size x contest weight
change is limited to plus or minus the cap (daily or season)
After that, the changes of established players are shifted by a whole-point amount so they add up to zero: points are never created among established players. Everything is whole numbers, so the same standings always give the same result on any machine.
Every setting
| Setting | Value | Why |
|---|---|---|
| Starting rating | 1200, marked provisional | A new player lands mid-table and climbs or sinks quickly |
| Placement | First 5 rated events, multipliers 2.0, 1.8, 1.6, 1.4, 1.2 | Finds a new player’s level in a week. After that the multiplier is 1.0 |
| Weekly season weight | 1.5 times a daily | A week of effort should count for more than one day |
| Smallest rated field | 8 players | Below that, a rank is mostly luck |
| Field-size weight | 0.3 at 8 players, rising evenly to 1 at 30 | Small early fields move ratings gently |
| Largest change in one event | 150 points daily, 200 for a season | One freak day cannot wreck or make a rating |
| Who counts in the field | Established players only, once 30 exist | Placement accounts cannot be used to feed points to others |
| Leaderboard | Players with 5 or more rated events who played in the last 30 days | The ladder shows people who are playing now |
| Account age | At least 14 days old on GitHub | A fresh start gains nothing, and fresh fakes cannot count |
| Rating range | 0 to 4000 | Ratings are kept inside this range |
The field-size weight is not a round number at in-between sizes; the engine’s source has the exact whole-number steps. The engine version is 1. If the maths ever changes, the version rises and every rating is recomputed from stored standings, so a bug is fixed by a rerun and never leaves a wrong number standing.
Tiers
Eight tiers, named for how a plant grows. Each has its own colour, used for the player’s name everywhere it appears: on every board, on the daily page and on profiles. The tier is also written out in words next to the rating, so colour is never the only signal.
| Tier | Rating | Name colour | Rough share of rated players |
|---|---|---|---|
| Evergreen | 2300 and up | Deep green with gold edge | Top handful |
| Grove | 2000 to 2299 | Gold | Top 1% |
| Orchard | 1800 to 1999 | Apple red | Top 5% |
| Bloom | 1600 to 1799 | Berry purple | Top 15% |
| Vine | 1400 to 1599 | Leaf green | Top 35% |
| Shoot | 1200 to 1399 | Light green | Middle |
| Seedling | 1000 to 1199 | Wheat | Lower third |
| Seed | Below 1000 | Soil brown | Bottom tenth |
The shares are what an Elo ladder usually settles into, not measurements. They will be checked after a month and the bands moved once if they are far off. The title is shown only after placement. Until then a profile says “In placement, 3 of 5”.
Fair play
| Abuse | Defence |
|---|---|
| Fake accounts placed below you to lift your rank | Beating a low-rated account is worth almost nothing. Accounts in placement do not count in anyone else’s field. A fake must also reach par and be 14 days old to be rated at all |
| A second account to start fresh | One rating per GitHub account, and a new start gains nothing anyway |
| Losing on purpose to lower a rating | Nothing is gained by a low rating |
| Copying a friend’s run | Identical logs are refused, and the same program from a second player is unrated for that day |
| Trading wins | Duels are unrated |
| Flooding with model runs | Declared models are ghosts and cannot move human ratings |
| Copying the leader during the day | Replays and sources stay sealed until the challenge closes |
Check the work
The engine is open: every number on this page is a constant in packages/rating
(constants.ts holds the settings, rate.ts the maths). A test fails the build if this page and the engine ever disagree. Each line of your
rating history links to that day’s replay, so anyone can watch the run that earned the points.
See the rating ladder.