DEV Community

Cover image for Measured tier lists, modelled draft picks: how I built BrawlPick for Brawl Stars
brawlpick
brawlpick

Posted on AI-assisted

Measured tier lists, modelled draft picks: how I built BrawlPick for Brawl Stars

Disclosure: I'm Tom, the maker of BrawlPick. It's a free fan project and isn't affiliated with Supercell.

In Brawl Stars' Ranked mode, both teams ban and pick brawlers before the match starts. Pick a brawler that doesn't suit the map, or one the enemy has an easy answer to, and you're behind before anyone moves. BrawlPick is a draft helper for that moment, plus public map and counter pages with measured statistics. Those are two different kinds of output, and keeping them apart was the most interesting part to build: the tier lists only show what was measured, and the draft helper is a model that is labelled as one.

The problem with "best brawler" lists

Most tier lists show a win rate and nothing else. A brawler at 71% looks better than one at 63%, until you learn the 71% comes from 38 games and the 63% from 1,400. With 38 games, the true win rate could plausibly be anywhere between about 55% and 83%.

Where the data comes from

BrawlPick reads recent battle logs from the official Brawl Stars API. Collection starts from a set of seed players (player tags that users saved, public leaderboards and members of top clubs) and then follows the other players found in those battles, which widens the sample to tens of thousands of players.

A few rules keep the counts honest:

  • Every battle is identified by its timestamp plus all six participants' tags, so a battle seen through several players is counted once, also across collection runs.
  • Only 3v3 battles with a win or a loss count. Draws and other modes are skipped; Ranked and regular matches are both included.
  • The API only returns each player's most recent battles (about 25), so a run mostly captures the last few days.

This is not a random sample of all players. Starting from leaderboards and top clubs probably tilts it towards active, higher-skill players, and the site says so next to the numbers.

Tier lists: ranking by the low end of a Wilson interval

Instead of sorting by raw win rate, every "best" list on the statistics pages is ordered by the lower bound of a 95% Wilson score interval:

// Lower bound of the 95% Wilson score interval, as a fraction (0–1).
function wilsonLower(wins: number, games: number, z = 1.96): number {
  if (games === 0) return 0
  const p = wins / games
  const z2 = z * z
  const centre = p + z2 / (2 * games)
  const margin = z * Math.sqrt((p * (1 - p)) / games + z2 / (4 * games * games))
  return (centre - margin) / (1 + z2 / games)
}
Enter fullscreen mode Exit fullscreen mode

For the two brawlers above, 63% over 1,400 games has a lower bound of about 60.4%, while 71% over 38 games ends up at about 55.2%. The brawler with more evidence ranks first, and the raw win rate is still shown next to its range.

On top of that ordering there is an explicit bar: a pick is only called "reliable" with at least 150 games and a 95% range entirely above 50%. The map and mode pages turn the same interval into tiers. S means the whole range is at least 5 points above 50%, A means it is entirely above 50%, and C and D mirror that below 50%. B means "this sample can't tell yet", not "average". Brawlers with fewer than 150 games are marked as limited data instead of being dropped into the bottom tier.

Counters: separating real counters from strong brawlers

A brawler that beats everyone also beats any single brawler, so a raw head-to-head win rate overstates counters. Each matchup is compared with what the two brawlers' usual win rates alone would predict: the counter's usual win rate minus the other brawler's, plus 50%. If that expected value falls outside the matchup's 95% range, the difference is marked as a clear edge. A matchup needs 100 games before its win rate is shown at all. It's a simple first approximation, not a model of everything that happens in a match, and the page says that too.

The draft helper is a model, not a statistic

The draft helper does not rank by the Wilson interval. It is a rule-based scoring model that gives every brawler still available a fit score, built from:

  • game mode and map fit, from hand-maintained class and trait data (role, range, map layout),
  • counter value into the enemy picks, from class matchups and per-brawler counter rules (not the measured matchup data above),
  • synergy with your team and the roles it is still missing,
  • early in the draft, how safe a pick is across different enemy picks.

Measured win rates do feed into the map and mode fit (plus a small separate win-rate term). Below 30 games they are shrunk toward neutral, so five lucky games can't push a brawler up, and as one factor among several they never outweigh the draft context. The weights shift as the draft goes on: flexibility matters more early, countering and role coverage more late. Bans and picks are a hard filter, not a penalty. Power level only decides whether a brawler you own counts as available for Ranked; it never changes the score.

The fit score runs from 0 to 100 and the app labels it as an algorithmic fit, not a chance to win. Suggestions list their reasons, and where measured data exists, that includes the observed win rate on the map and how many games it is based on. Because the model and the statistics differ, the picker's top pick can be a brawler that isn't first in any table, and the counter pages show the two side by side, labelled separately.

Stack

A Next.js app running on Cloudflare Workers (via OpenNext), with Supabase for accounts and data, and an iOS app built with Capacitor. The public pages apply stricter minimum sample sizes than the picker uses internally, so a number that is fine as one input among many isn't presented as a standalone claim.

Try it

I'd like feedback on two things. Does ordering tier lists by the lower bound match your intuition as a player? And where does a draft suggestion look wrong to you?

Top comments (0)