How we rank raid counters
The DPS × Effectiveness × Bulk formula behind every counter list on Hundo Hunter.
Counters are ranked by a single composite score: DPS × Type Effectiveness × Bulk^0.5, weighted per-role (offensive raids weight DPS, defensive raids weight bulk). The score is closed-form and rebuilds every counter list in under 1ms per boss.
Every ranking on a raid-counter page comes down to three measured numbers: how fast the attacker dishes damage (DPS), how much that damage gets amplified or muted by the boss's typing (effectiveness), and how long the attacker stays in the fight (bulk).
A glass cannon with 360 DPS that faints in 6s puts out 2 160 damage and then exits. A balanced attacker with 280 DPS that survives 18s puts out 5 040 damage in the same window. Both numbers matter, neither alone is enough.
score = dps × type_eff × bulk^0.5 × role_weight dps = top-moveset DPS published by PvPoke or PokeBattler type_eff = ∏ (1.6 if SE on boss type) × (0.625 if resisted) × (0.39 if double-resist) bulk = (HP × Def) / 10 000 // raw bulk product, normalized role_weight = 1.0 for offensive raid; 0.85 dps + 1.15 bulk for "tank" raid
We use bulk^0.5 (a square root) instead of raw bulk because survival has diminishing returns — doubling HP × Def does NOT double effective damage output; it adds maybe 30%.
The role weight kicks in for bosses with brutal charged moves where survival is the bottleneck (e.g. Mewtwo Psystrike, Primal Groudon Solar Beam). We boost the bulk component by ~15% and trim DPS weight accordingly.
PokeBattler runs a Markov-chain simulation of the full fight including dodge mechanics, energy gain over time, and faint-revive cycles. Their numbers are the ground truth — but at ~100ms per attacker × moveset, you can't run it for 1 200 species × 5 movesets each at request time on a static site.
Our closed-form score reproduces ~90% of PokeBattler's top-12 ordering at <1ms per attacker. We benchmark against PokeBattler quarterly. When ordering drifts more than 1 position for a top-10 entry, we adjust the role_weight constants.
PvPoke's PvE rankings use a different weighting that under-rates Megas (because of cost-per-investment) — we instead surface Megas at the top of the list because the user is usually optimizing for a 5-star or 6-star boss they will retry many times.
The closed-form score deliberately ignores some second-order effects:
- ▸Dodge timing — never modeled. Most casual raiders do not dodge consistently anyway.
- ▸Energy carryover from previous fight — we assume each attacker enters with 0 energy.
- ▸Relobby cost — we assume the lobby refills in time before the boss expires.
- ▸Mega buff to teammates — surfaced as a separate note on the counter page, not folded into the score.
How Hundo Hunter solves the CP formula backward to find IVs.
How Hundo Hunter ranks the top 12 counters for every raid boss.
How Hundo Hunter curates the top-12 picks per league.
How Hundo Hunter computes the hundo and floor CP for every raid catch.
How Hundo Hunter assigns S / A+ / A / B / C tiers to attackers.
How Hundo Hunter maps the in-game appraisal stat bars to exact 0-15 IVs.
The 91% IV threshold, XL-relevance check, and per-species candy economics behind every Pinap recommendation.
Per-level CPM math, Lucky halving, Best Buddy stack, and why our estimates can differ from in-game by 1-2%.
ASC API + ct= campaign tokens, per-source attribution, and zero personal data on the install funnel.
LeekDuck → ScrapedDuck → our API, with 1-hour refresh, Postgres translation cache, and graceful fallback.
Where the "mons" / "the game" convention applies, where the trademarked name is allowed, and why.
Vercel Analytics, no personal tracking, opt-in email only, and stateless HMAC unsubscribes.