Repository navigation
Build Styles
Some heroes have more than one established build at high rank. Warden is the clearest case: most Phantom+ games are gun Warden (Quicksilver Reload, Opening Rounds, Titanic Magazine, Mercurial Magnum), but a steady minority are spirit/cooldown Warden (Arcane Surge, Compress Cooldown, Duration Extender, Superior Cooldown), and the two share almost nothing. One build scored against a panel that contains both kinds of player can never do better than the bigger camp, which is why Warden sat at 52% before this was added. When a hero has two established builds the app shows both, each generated only from the games played that way.
Styles are detected at fetch time (scripts/styles.mjs, called from scripts/fetch-data.mjs) from
aggregate data only; no per-player data is involved. The API's item-stats endpoint accepts
include_item_ids / exclude_item_ids, which gives the hero's item usage conditional on some item
having been bought (or not). The pair statistics the snapshot already had cannot do this: they are top-600
lists that miss exactly the minority items a second style is made of.
- Candidate anchors: every item bought in 4% to 70% of the hero's Phantom+ games (items above 70% are shared by every style; below 4% there are too few games). About 40 to 60 items per hero, one API call each.
- For each anchor, compare the conditional usage profile with the population:
- displacement: the usage-weighted share of the hero's staples (items at 50%+ usage) that fall below half their normal usage in the anchor's games;
- new core: items that reach 50%+ usage in the anchor's games with at least 1.8x their normal usage.
- An anchor defines a style when its games are at least 5% of the hero's games, displacement is at least 0.3, and there are at least 2 new-core items. Anchors that pass are grouped: when either is bought in half or more of the other's games they are the same style (the group keeps up to 4 anchors). At most two alternative styles are kept, biggest first.
- Populations: each alternative style is the item and ability-order stats of the games where its seed
anchor was bought; the main style is the population with every alternative anchor excluded. Pair
(synergy) stats stay unconditional. Everything is stored under
top.stylesinanalytics/<hero>.json.
The generator (stylePopulations in src/generator/build.ts) uses the styles only when the hero's
high-rank population is the one being used and every style has at least 300 matches behind it; otherwise
the hero gets one build as before. Each build is then generated with the normal scoring function from its
own population, so the alternative build is "what people who go that way buy, in the order they buy it",
not the main build with a few items swapped.
A build is named after the slot type of its defining items: the items bought in 40%+ of its games and at least 15 points more often than in any other style. Weapon items give "Weapon build", spirit "Spirit build", vitality "Vitality build". If two builds would get the same name the alternative is named after its seed item and the main one becomes "Standard build". The tagline says which item the style is built around and what share of the hero's high-rank games go that way.
With more than one build, each panel player is scored against the build that fits them best and the
per-player scores are combined with the usual selection-score weights (panelAgreementAcrossBuilds). A rep who
plays spirit Warden is compared with the spirit build, not penalised for ignoring the gun build. This is the
number npm run verify and scripts/tune.ts report; the per-build agreement is still shown in the app under
each build.
Twenty heroes now ship two or three builds. Their cross-build panel agreement and how the panel splits between the builds (a rep counts for the build they agree with most):
| hero | agreement | panel split |
|---|---|---|
| Infernus | 78% | Standard build 4 reps, Headhunter build 1 reps |
| Vindicta | 76% | Weapon build 5 reps, Spirit build 0 reps |
| Lady Geist | 70% | Weapon build 5 reps, Spirit build 0 reps |
| Abrams | 77% | Weapon build 2 reps, Spirit build 3 reps |
| McGinnis | 72% | Standard build 5 reps, Quicksilver Reload build 0 reps |
| Paradox | 74% | Weapon build 2 reps, Spirit build 3 reps |
| Bebop | 68% | Weapon build 3 reps, Spirit build 2 reps |
| Grey Talon | 78% | Spirit build 5 reps, Weapon build 0 reps |
| Shiv | 79% | Spirit build 5 reps, Weapon build 0 reps |
| Ivy | 69% | Standard build 1 reps, Fleetfoot build 2 reps, Spirit build 2 reps |
| Warden | 63% | Weapon build 2 reps, Spirit build 3 reps |
| Viscous | 72% | Standard build 3 reps, Close Quarters build 0 reps, Spirit build 2 reps |
| Sinclair | 85% | Spirit build 5 reps, Vitality build 0 reps |
| Drifter | 68% | Spirit build 1 reps, Weapon build 2 reps, Vitality build 2 reps |
| Venator | 83% | Weapon build 0 reps, Vitality build 5 reps |
| Victor | 75% | Spirit build 4 reps, Weapon build 0 reps, Vitality build 1 reps |
| The Doorman | 77% | Standard build 3 reps, Golden Goose Egg build 2 reps |
| Graves | 77% | Spirit build 5 reps, Weapon build 0 reps |
| Apollo | 82% | Spirit build 5 reps, Weapon build 0 reps |
| Silver | 65% | Weapon build 5 reps, Spirit build 0 reps |
Across all 38 heroes the mean panel agreement went from 70.7 % to 72.7 % and the median from 70 % to 74 %. Warden went from 52 % to 63 % (two gun reps, three spirit reps). Drifter 54 % → 68 %, Ivy 61 % → 69 %, Paradox 63 % → 74 %, Abrams 70 % → 77 %, Bebop 64 % → 68 %. Heroes with one style are unchanged apart from data refresh noise. Half of the two-build heroes have every rep on one build; the second build there describes a real but less common way to play (for example Vindicta with Alchemical Fire, 13 % of games), and it costs nothing in the metric because each rep takes the closer build.