Reading the screenshot
You give the app a screenshot of champion select — either uploaded or captured directly from your screen. That image is read by a local OCR engine (Tesseract) running on the server, which picks out the ten champion names across both teams. Champion names and portrait icons, used throughout the app, come from Riot's public Data Dragon service. Nothing about the screenshot leaves the server, and it's never written to disk: once OCR has read the picks off it, the image itself is discarded. See the privacy policy for the full detail on what is and isn't retained.
OCR isn't perfect. It can misread a champion, especially on a compressed image — a screenshot re-encoded as JPEG measurably resolves fewer champions than the same image saved as PNG, because compression artifacts blur exactly the kind of small text OCR depends on. If a slot comes back wrong or blank, you can correct it by hand before the app scores the lobby.
From a win rate to a probability
Once the ten champions are known, each one gets looked up against a third-party League of Legends statistics provider for its aggregate win rate at your rank (or, if you haven't entered a Riot ID, pooled across all ranks). That win rate is the provider's own aggregation of League of Legends match data that originates with Riot Games — Riot doesn't itself publish win-rate statistics. That raw win rate is first clamped to a range of 30% to 70%. This matters because win rates from small sample sizes can be extreme — a champion with three recorded games and two wins isn't actually a 67% win-rate champion, it's a coin flip with too little data behind it. Clamping stops a result like that from dominating the calculation.
The clamped win rate is then converted to a log-odds value — the same transformation behind logistic regression, which turns a bounded probability into an unbounded number that can be added and subtracted meaningfully. Every ally champion's log-odds contribution is summed, every enemy champion's is summed separately, and the enemy total is subtracted from the ally total. That net figure is passed through a sigmoid function, which maps it back onto a 0–100% probability. The result is your team's estimated win probability for that lobby.
Why the raw percentage isn't the whole story
A bare number like "54%" doesn't tell you much on its own. Is that a strong lobby or a completely ordinary one? The answer depends on how spread out the model's outputs typically are — and that spread turns out to be different at every rank.
To find out how spread out, an offline simulation ran 400,000 simulated ten-champion lobbies for each of 11 tier scopes (Iron through Challenger, plus an all-tiers scope), drawing champions in proportion to their real pick rate within each role and scoring every lobby through the exact formula above. The resulting distribution of outputs turned out to be almost exactly normal, and centred on 50% at every single tier — which makes sense, since a lobby assembled from realistic picks should be as likely to favour one side as the other on average. Because the shape is so cleanly normal, each tier's spread can be described by a single number: its standard deviation.
The standard deviations, and a genuinely surprising result
Here they are, in percentage points:
- Iron: 7.59
- Bronze: 6.07
- Silver: 5.85
- Gold: 5.45
- Platinum: 5.00
- Emerald: 4.53
- Diamond: 4.40
- Master: 4.77
- Grandmaster: 7.50
- Challenger: 12.23
- All tiers combined: 4.78
Look at the shape of that list. It isn't a straight line from "low rank, high spread" to "high rank, low spread" — it's a curve that narrows through the middle of the ladder and then widens sharply again at the very top. Diamond has the tightest distribution of any tier, and Challenger's is nearly three times wider. That's not a typo and not a different model running at different ranks — it's the same formula, the same clamping, the same log-odds sum, run against real pick data at each tier.
The three wide tiers — Iron, Grandmaster, and Challenger — reflect genuinely noisy per-champion win rates at those tiers: individual champions' win rates swing harder from patch to patch and week to week there, even after clamping limits how far any single one can push the total. That's clearest at the top: Challenger is a few hundred players per region, not the hundreds of thousands playing Gold or Silver, so its champion win-rate samples are thinner and noisier, and Grandmaster isn't far behind it. Iron sits at the other edge of the ladder for reasons the calibration itself doesn't explain.
What the calibration doesn't tell us is why the tightest tier is Diamond rather than, say, Silver or Gold, which have far larger player populations. If population size alone drove the spread, those high-population mid tiers would be the tightest on the list, and they aren't — Diamond is, at 4.40, tighter than Gold's 5.45. One plausible explanation is that champion win rates are simply more dispersed at lower ranks generally, independent of sample size, so the same formula produces a wider spread of lobby totals there — but that's a hypothesis, not something this simulation established. What the numbers do establish firmly is the practical consequence: a given win-probability reading, say 60%, is an unremarkable result in Challenger (roughly 0.8 standard deviations from 50%) and a genuinely uncommon one in Diamond (roughly 2.3 standard deviations out). The number means something different depending on where it's measured, which is exactly why this calibration exists.
Turning a percentile into a verdict
With a tier's standard deviation known, any given win probability can be converted into a z-score — how many standard deviations it sits from that tier's 50% centre. That z-score sorts the reading into one of five bands:
- Neutral covers the middle 38.3% of lobbies — readings within half a standard deviation of 50%.
- Low and High each cover 24.2% of lobbies — readings between half and one and a half standard deviations out.
- Really low and really high each cover the remaining 6.7% — readings more than one and a half standard deviations from 50%.
That last figure is worth sitting with: "really low" or "really high" genuinely means a roughly 1-in-15 lobby, not just "a bit below average." The bands are calibrated to be rare when they say rare.
Partial lobbies
Champion select doesn't always give you all ten picks before you want a read on it — some slots may still be unpicked, or OCR may not have matched a portrait yet. The app scores whatever it has rather than waiting for a full lobby.
An empty slot is simply left out of the sum entirely, rather than filled in with some placeholder value. That's the unbiased choice: a random, not-yet-known champion's expected log-odds contribution is approximately zero, so omitting it doesn't push the result toward either team.
What does change is the band the result falls into. With fewer champions locked in, the model widens the tier's standard deviation rather than narrowing it, and never narrows it below the full-lobby value. That might seem backwards — shouldn't fewer inputs mean a tighter, more confident reading? It's the opposite. A six-champion reading is a noisy early estimate of where the eventual ten-champion lobby will land, not a more precise version of it. Narrowing the bands as picks come in would mean the app delivers its loudest verdicts — "really low," "really high" — on its weakest evidence, right when the fewest picks are locked in. Widening keeps a partial reading appropriately cautious: a 6-champion lobby needs to drift further from 50% before it earns an extreme label than a full 10-champion lobby does.
What this doesn't know
It's worth repeating plainly: this model has no idea about player skill, champion mastery, specific matchups, team synergy, or the order picks happened in. It works from aggregate win rates alone. Those win rates are also patch-bound — a balance patch can shift them meaningfully, and the app is only ever as current as the match data it's aggregated from.
On top of the model's own limits, there's the OCR layer underneath it: it can misread a champion, particularly from a compressed screenshot, so always glance at the recognised picks before trusting the verdict. Treat the output as a rough signal about the picks themselves, not a forecast of the game.