Skip to content

About

A validated damage & time-to-KO model for Pokémon Unite — quantifying how much Lv40 held items, emblems, and X Attack actually speed up your knockouts, across all 94 Pokémon. (~+53% pre-evo burst; items > X Attack > emblems.)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

Pokémon Unite — Stat Investment vs. Time-to-KO

Does maxing your account — Lv 40 held items, gold emblems, X Attack — let you knock people out before they evolve, regardless of which Pokémon you play? Enemy builds are unobservable in-game, so this answers it with a model: a damage / time-to-KO engine built from current, validated unite-db data and the game's verified damage formula, run across the full 95-Pokémon roster — base moves, Lv5/7 upgrades, enhanced forms, multi-hit, and execute included.

TL;DR

  • 📉 Maxed investment adds ~53% to pre-evo burst (≈ a third less time-to-KO overall, and closer to half for pure auto-attackers) — and it holds regardless of Pokémon.
  • 🔧 Which lever? Of that gain: items ~57%, X Attack ~32%, emblems ~11% — and emblem rarity barely matters (no-emblems → gold is +4.6% burst; bronze → gold is ~1%). Emblems are optimized over the real 762-emblem set as realistic 6-damage + 4-bulk pages (colors, grades, tradeoffs).
  • 🧪 Validated: computed move damage matches Game8 within 0.4% across base moves and upgrades (Cinderace Pyro Ball exactly 1774). 28 tests green.
  • 🤔 Honest limit: raw combat power barely predicts the community tier (Spearman +0.06). The model nails "who hits hardest pre-evo" — but "who's actually good in ranked" is range, mobility, CC, objectives, and scaling, which it deliberately doesn't model.

🏆 Best Pokémon & build per role

Brute-forces every legal 3-item combo × emblem template per Pokémon (a maxed account), ranking offense by burst and sustained DPS (CDR-aware), tanks/supports by effective HP with shields up:

Best Pokémon and build per role

Per-role detail charts (burst · DPS · survivability)

Top burst by role Top DPS by role Survivability

"Best by modeled combat metric" — see the meta check below for how much that actually predicts viability. Shields are counted "up" (situational).

Same analysis at full build (Lv 15)

The chart above is Lv 5 (pre-evo), the level the offensive study uses (where unite-db's move data is Game8-validated). But survivability is pure stats available at every level, and tanks come online late — so Lv 5 under-rates them. Re-running the same optimizer at Lv 15 (full build) — python src/optimize.py --level 15 — reshuffles the board, most dramatically for Defenders:

Best Pokémon and build per role — Lv 15 full build

The best Defender flips Articuno → Goodra (Goodra is last at Lv 5 but first at Lv 15; Blastoise climbs #13 → #3), and the best Supporter swaps Wigglytuff → Meganium. Offense moves too (Speedster burst Leafeon → Darkrai; All-Rounder Pawmot → Feraligatr). The slope chart makes the defensive churn explicit — identical metric, only the level changes:

Defender / Supporter survivability rank — Lv 5 vs Lv 15

Per-role Lv 15 detail charts (burst · DPS · survivability)

Top burst by role — Lv 15 Top DPS by role — Lv 15 Survivability — Lv 15

Faithfulness: Lv 15 uses the same validated engine — base + Lv 5/7 upgrade moves are Game8-checked (e.g. Pyro Ball), while Lv 11/13 enhanced forms are modeled from unite-db (not in the Game8 sample). The defensive ranking is pure stats, so it's unaffected by that caveat.

What the Score column means

It isn't one unit — it's whatever metric the Best by column names, computed against a fixed reference dummy (an un-invested Cinderace at Lv 5) and reported for the build that maximizes it (brute-forced over every legal 3-item combo × emblem page):

Best by Score = computed in
Burst post-mitigation damage of casting every kit move once (best Lv 5 form, with X Attack) + autos landing in a 2.0 s window optimize.burst_damage
DPS auto-attack DPS + Σ(move damage ÷ effective cooldown), CDR-aware optimize.sustained_dps
Eff. HP raw damage needed to drop the build (avg of physical/special) + shield HP optimize.survivability

It's an argmax, not a stat: burst and DPS are optimized independently, so a Pokémon's two rows can list different builds. Scores are not comparable across rows (damage over ~2 s vs damage-per-second vs hit points). And it's a modeled score — the meta check shows it barely tracks real viability (Spearman +0.06).

🔧 Which lever actually matters? (the original question)

Lever decomposition

Of the +53% burst that investment adds over base stats (Lv 4, averaged over 69 offensive mons): items ~57%, X Attack ~32%, emblems ~11%. The emblem-rarity sweep shows the jump is just having a page at all (none → bronze +3.6%); bronze → gold is ~1%. (Emblem pages are a real optimization over unite-db's 762 emblems — colors, grades, and stat tradeoffs — built as realistic 6-of-the-damage-color + 4-bulk pages, not glass-cannon stacks; emblems come out even smaller this way, so the conclusion is robust.) Practical takeaway: upgrade your held items first; emblems are a small edge and their rarity is close to noise.

📉 Headline — investment ~halves pre-evo auto-attack time-to-KO

Basic attacks only (the cleanest lever view), maxed attacker vs. an un-invested squishy:

@ Lv 3 un-invested maxed reduction
Cinderace 24 hits / 21.5 s 13 hits / 10.4 s 46% / 52%
Zeraora 18 hits / 15.9 s 11 hits / 8.7 s 39% / 45%
Pikachu 24 hits / 21.5 s 13 hits / 10.4 s 46% / 52%

Hits to knock out, maxed vs un-invested

(Autos are 100% stat-scaled, so investment helps them most; abilities carry a big flat/level base, so investment is diluted there — which is why the combined effect is ~+53%, not ×2.)

🤔 Does the model agree with the meta?

Meta validation

No — Spearman +0.06. Modeled combat power does not predict unite-db's community tier (best for Defenders +0.51, where bulk is the job; even slightly negative for Attackers). This is the most important guardrail in the project: the engine is accurate (validated vs Game8) but measures one narrow thing. "Who's actually good" depends on range, mobility, CC, objective control, and late-game scaling — none of which this models.

Sources & verification

  • Stats, moves & emblems — unite-db raw JSON (/pokemon.json, /stats.json, /emblems.json): the Mathcord-sourced data its site loads — 95 mons + 762 emblems. Its pages are JS-rendered (unreadable to a fetcher); the /*.json endpoints are raw. The full move kit (base + upgrades + enhanced_ + multi-hit + execute + per-level penetration/CDR) and real emblem pages (colors / grades / stat tradeoffs) are derived from it. Cached in data/unite_db_*.json.
  • Held/battle items + emblems — Game8 (Lv40 tables, emblem rarity + color sets), patch v1.21.1.8 (2026-05-14).
  • Damage formula — reference engine Stephen-Choi/...: mitigation floor(atk × 600/(600+Def)) + attack-speed buckets, taken verbatim. (It is stale on rebalanced moves, e.g. Electro Ball — so unite-db, validated vs Game8, is the trusted source.)
  • Validated: src/validate.py reproduces Game8's published move totals within 0.4% (Pyro Ball = 1774 exactly) across base + upgrade moves and multiple levels. 28 tests cover the formula, Blastoise 35%, attack-speed buckets, Muscle Band cap, the move formula, the Game8 cross-check, and the input-provenance proofs below.
  • Inputs are provable — src/validate_inputs.py proves every value that feeds a score traces to its source, in two ways. Provenance (strong, 100% coverage): data/pokemon.json (every mon's attack + per-level stats — 95 mons × levels) and data/moves.json (every cooldown — 750 base/upgrade/enhanced forms) are exactly reproducible from the cached raw unite-db JSON, so each value equals its source, not a hand-edited copy. Cross-check / snapshot: held items match a Game8 Lv 40 snapshot (each tagged with its Game8 archive id) and are verified to be applied in make_build; emblems use the intact 762-emblem set with color bonuses that cap correctly and page stats that re-sum from the named emblems; the X Attack multipliers in the pure engine equal data/battleitems.json. (Magnitude cross-checks of raw numbers live in validate.py; item/emblem/X-Attack values are locked to patch v1.21.1.8 — re-run the pipeline to refresh from source.)

Run

pip install -r requirements.txt
python -m pytest tests/ -q          # 28 tests
python src/validate.py              # #1 move damage vs Game8
python src/validate_inputs.py       # #1b prove each score input (stats/cooldowns/items/emblems/X Attack) traces to source
python src/optimize.py              # Phase 2 per-role optimizer + charts + CSV
python src/optimize.py --level 15   # full-build (Lv 15) variant of the per-role charts
python src/decomposition.py         # #2 lever decomposition + emblem-rarity sweep
python src/defensive_items.py       # per-item HP/Def/Sp.Def -> effective-HP breakdown + chart
python src/defensive_ranking.py     # best tank/support: Lv 5 vs Lv 15 rank shift (slope chart)
python src/meta_validation.py       # #5 model vs community tier
python src/emblems.py               # exact named emblem pages -> data/emblem_pages.txt
python src/abilities.py             # pre/post-evo burst combos
python src/analysis.py              # Phase 1 auto-attack hits-to-KO

# Refresh data from unite-db (re-cache + regenerate the derived files):
python src/fetch_unitedb.py ; python src/parse_unitedb_moves.py ; python src/build_pokemon_from_unitedb.py

Project layout

data/   unite_db_*.json (source) · pokemon.json / moves.json (generated) ·
        helditems / battleitems / emblems.json (Game8)
src/    stats.py · damage.py (engine) · builds.py · emblems.py (emblem optimizer) ·
        abilities.py (full-kit combat) · optimize.py (Phase 2) · decomposition.py ·
        meta_validation.py · validate.py · validate_inputs.py · analysis.py ·
        fetch_unitedb / parse_unitedb_moves / build_pokemon_from_unitedb (pipeline)
tests/  engine, move-formula, and Game8-validation tests
figures/ exported charts

Status & caveats

  • ✅ Engine (full kit, CDR, penetration, shields) · ✅ validated vs Game8 · ✅ per-role optimizer · ✅ lever decomposition · ✅ meta validation.
  • Modeled at Lv 5 by default (upgrades begin coming online); the engine handles any level — python src/optimize.py --level 15 renders the full-build variant (and the board reshuffles).
  • Not modeled: melee boosted (every-3rd) basics, crit-damage scaling (Scope Lens with high Attack), and CC (a stun lets the full combo land uncontested — often the real reason you get knocked out). Shields are counted "up" (situational). The burn-DoT ratio on a couple moves differs ~2× from Game8 (a small secondary component).
  • Biggest caveat (measured, not assumed): combat power weakly predicts viability (Spearman +0.06). Treat the per-role tables as "hardest-hitting pre-evo," not a tier list.

License

MIT. An unofficial fan project — not affiliated with or endorsed by The Pokémon Company, Nintendo, or TiMi Studios. Game data is sourced from unite-db and Game8 for analysis; all trademarks belong to their respective owners.

About

A validated damage & time-to-KO model for Pokémon Unite — quantifying how much Lv40 held items, emblems, and X Attack actually speed up your knockouts, across all 94 Pokémon. (~+53% pre-evo burst; items > X Attack > emblems.)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages