DEV Community

Cover image for Most pack-opening simulators invent their pull rates — here is what ours actually look like
PullSim
PullSim

Posted on Edited on Originally published at pullsim.com

Most pack-opening simulators invent their pull rates — here is what ours actually look like

Almost every pack-opening simulator does the same thing: the percentages are hard-coded constants. No sample size, no source date, and no way to tell whether a rate came from a published study or from someone's best guess. If the number is wrong, you cannot even tell that it is wrong.

PullSim is my attempt to build one the other way round. This post is about the awkward part: what the published samples actually support, and where they contradict themselves.

TL;DR — the three sets we model have rarest-tier rates of 0.19%, 0.56% and 0.08%. The widest is roughly 7× the narrowest. Each of those numbers rests on a single-digit count of observed packs, which is why every rate ships with the interval next to it instead of a bare percentage.

A rate without a sample size is not a measurement

Here are the three sets we model, with the sample each rate rests on:

Set Packs in the source sample Rarest modelled tier Rate Reported 95% interval
Ascended Heroes 2,000 Mega Hyper Rare 0.19% ±0.18%
Prismatic Evolutions 1,200 rarest modelled tier 0.56% ±0.41%
Phantasmal Flames 5,000 rarest modelled tier 0.08% ±0.08%

A single hard-coded table reused across every set cannot be right for all of them — 0.56% and 0.08% are the same species of claim and a factor of seven apart. That is exactly what most simulators ship.

The interval is the interesting part

Look at the Mega Hyper Rare row: 0.19% with an interval of ±0.18%. The interval is almost as large as the estimate itself. That is arithmetic, not noise. 0.0019 multiplied by 2,000 gives about 3.8 expected hits, so the entire estimate for that tier rests on roughly four packs out of two thousand.

Phantasmal Flames tells the same story from the other direction: 0.08% of 5,000 packs is also about four packs, on a sample two and a half times larger.

That is the actual state of knowledge, and printing it is the whole difference between a measurement and a number someone typed.

The per-tier schema is deliberately boring: ratePct, ciPct and samplePacks sit next to poolSize, sourceUrl and sourceDate for every tier, plus alternateRatePct wherever the source article contradicts itself. Null means not established — never zero.

Where the source articles contradict themselves

I found three cases and kept all of them visible instead of quietly picking one:

  1. Ascended Heroes, Ultra Rare — 4.81% in the main table, 20.77% in a detailed section. The main-table figure drives the simulation (it is the set-level summary); the other value is preserved as a note.
  2. Prismatic Evolutions, Double Rare — 16.51% ±2.05% in the main table, 16.94% ±0.79% in the detailed section. The main-table value drives the simulation; the alternate is preserved.
  3. Prismatic Evolutions, Specific Double Rare — the article reports 0.94%, but dividing the adopted 16.51% by its 25 cards gives about 0.66%. I could not reconcile the two, so I derive the single-card estimate myself instead of quoting the reported figure.

A dataset that hides these becomes easier to read and less true at the same time.

Normalising percentages is a bug, not a simplification

Each published tier rate is already an absolute per-pack probability inside a specific slot. The tempting fix is to divide every tier by the sum of the tiers so the numbers add up to 100%. That answers the wrong question.

Prismatic Evolutions' Special Illustration Rare rate is 2.22%. Flatten the slot so the listed hits must sum to a full outcome and that figure climbs to roughly 29%. No sample supports that. What disappeared was the ordinary reverse-holo remainder — the most common outcome in the slot. The correct model draws one random number, walks the tiers by their unmodified cumulative rates, and returns the base card when no threshold is crossed.

What the data cannot support yet

Null means not established, never zero:

  • God Packs and Demigod Packs. The Prismatic source discusses both and notes what may have been two Demigod Packs, but could not confirm them. The description is stored, the rate stays null.
  • Poké Ball Foil / Master Ball Foil. These are patterns across cards, not standalone rarity categories, so dividing by the available pool gives a deliberately conservative single-card estimate rather than an invented one.
  • Delta Reign. Listed, no confirmed rate yet.

The data is open

The whole table — per-tier sample counts, card-pool sizes, source links, and every source conflict above — is published under CC BY 4.0:

The arithmetic behind every figure, written up with the three conflicts spelled out: https://pullsim.com/how-we-calculate/

If you model pack economics, or you just want to know what you are actually buying, recompute the numbers above and tell me where they break.

AI disclosure: drafted with AI assistance; every figure in this post was verified against the published source articles.

Top comments (0)