Gacha Pull Probability Calculator
ANA›Life Services Authority›National Calculator Authority›Gacha Pull Probability Calculator
.calc-container { max-width: 640px; margin: 2rem 0; padding: 1.5rem; background: #fff; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); font-family: system-ui, -apple-system, sans-serif; } .calc-container h3 { font-family: Georgia, serif; font-size: 1.15rem; color: #1a1a1a; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; flex-wrap: wrap; } .calc-row label { min-width: 160px; font-size: 0.9rem; color: #333; font-weight: 500; } .calc-row input[type="number"], .calc-row select { flex: 1; min-width: 120px; max-width: 200px; padding: 0.5rem 0.6rem; border: 1px solid #ccc; border-radius: 4px; font-size: 0.9rem; font-family: system-ui, sans-serif; color: #1a1a1a; background: #fafaf8; } .calc-row input:focus, .calc-row select:focus { outline: none; border-color: var(--ac, #3d5a80); box-shadow: 0 0 0 2px rgba(26,74,138,0.12); } .calc-row .unit { font-size: 0.82rem; color: #888; min-width: 30px; } .calc-btn { display: inline-block; margin-top: 0.5rem; padding: 0.55rem 1.5rem; background: var(--ac, #3d5a80); color: #fff; border: none; border-radius: 4px; font-size: 0.9rem; font-weight: 600; cursor: pointer; font-family: system-ui, sans-serif; } .calc-btn:hover { opacity: 0.9; } .calc-result { margin-top: 1.25rem; padding: 1rem 1.25rem; background: #f0f6fc; border-left: 3px solid var(--ac, #3d5a80); border-radius: 0 6px 6px 0; display: none; } .calc-result.visible { display: block; } .calc-result-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: #666; margin-bottom: 0.25rem; } .calc-result-value { font-size: 1.6rem; font-weight: 700; color: var(--ac, #3d5a80); } .calc-result-detail { font-size: 0.85rem; color: #555; margin-top: 0.5rem; line-height: 1.5; } .calc-note { margin-top: 1rem; font-size: 0.8rem; color: #888; font-style: italic; } .calc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-top: 0.75rem; } .calc-grid-item { padding: 0.6rem 0.8rem; background: #f8f9fa; border-radius: 4px; border: 1px solid #eee; } .calc-grid-item .label { font-size: 0.75rem; color: #888; text-transform: uppercase; letter-spacing: 0.04em; } .calc-grid-item .value { font-size: 1.1rem; font-weight: 600; color: #1a1a1a; } @media (max-width: 720px) { .calc-row { flex-direction: column; align-items: flex-start; gap: 0.3rem; } .calc-row label { min-width: auto; } .calc-row input[type="number"], .calc-row select { max-width: 100%; width: 100%; } .calc-grid { grid-template-columns: 1fr; } } .calc-chart { margin: 1rem 0; text-align: center; } .calc-chart svg { max-width: 100%; height: auto; } .calc-chart-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem 1.2rem; margin-top: 0.6rem; font-size: 0.8rem; color: #555; } .calc-chart-legend span { display: inline-flex; align-items: center; gap: 0.3rem; } .calc-chart-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; font-style: normal; } .calc-related { max-width: 640px; margin: 2rem 0 1rem; padding: 1.25rem 1.5rem; background: #f8f9fa; border: 1px solid #e8e8e8; border-radius: 8px; } .calc-related h3 { font-family: Georgia, serif; font-size: 1rem; color: #1a1a1a; margin: 0 0 0.75rem; padding-bottom: 0.4rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-related-list { list-style: none; padding: 0; margin: 0 0 0.75rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 1.5rem; } .calc-related-list li a { font-size: 0.88rem; color: var(--ac, #3d5a80); text-decoration: none; } .calc-related-list li a:hover { text-decoration: underline; } .calc-browse-all { margin: 0.5rem 0 0; font-size: 0.9rem; font-weight: 600; } .calc-browse-all a { color: var(--ac, #3d5a80); text-decoration: none; } .calc-browse-all a:hover { text-decoration: underline; } @media (max-width: 720px) { .calc-related-list { grid-template-columns: 1fr; } }
Gacha Pull Probability Calculator
Calculate the probability of pulling a desired item in gacha/loot box systems, including pity system mechanics.
Base Drop Rate per Pull (%)
Number of Pulls
Pity System (Hard Pity at Pull #, 0 = no pity)
Soft Pity Start (Pull #, 0 = no soft pity)
Soft Pity Rate per Pull (%)
Number of Desired Items Wanted
Cost per Pull (optional, e.g. gems/currency)
Calculate Results will appear here.
function gacCalc() { var baseRateInput = parseFloat(document.getElementById('gac-base-rate').value); var numPulls = parseInt(document.getElementById('gac-num-pulls').value); var pity = parseInt(document.getElementById('gac-pity').value); var softPity = parseInt(document.getElementById('gac-soft-pity').value); var softRateInput = parseFloat(document.getElementById('gac-soft-rate').value); var desired = parseInt(document.getElementById('gac-desired').value); var costPerPull = parseFloat(document.getElementById('gac-cost').value);
// Validation if (isNaN(baseRateInput) || baseRateInput 100) { document.getElementById('gac-result').innerHTML = 'Error: Base drop rate must be between 0.001% and 100%.'; return; } if (isNaN(numPulls) || numPulls 10000) { document.getElementById('gac-result').innerHTML = 'Error: Number of pulls must be between 1 and 10,000.'; return; } if (isNaN(desired) || desired 100) { document.getElementById('gac-result').innerHTML = 'Error: Desired items must be between 1 and 100.'; return; } if (pity Error: Pity value cannot be negative.'; return; } if (softPity Error: Soft pity start cannot be negative.'; return; } if (softPity > 0 && pity > 0 && softPity >= pity) { document.getElementById('gac-result').innerHTML = 'Error: Soft pity start must be less than hard pity.'; return; } if (isNaN(softRateInput) || softRateInput 100) { document.getElementById('gac-result').innerHTML = 'Error: Soft pity rate must be between 0% and 100%.'; return; }
var baseRate = baseRateInput / 100; var softRate = softRateInput / 100;
// Build per-pull probability array accounting for pity // pullProb[i] = probability of success on pull i (1-indexed), given no success yet // We simulate using a probability distribution over "pulls since last success" // P(get item on pull n | no item yet) uses the conditional probability chain
// Step 1: Build rate for each pull index within a pity cycle function getRateAtIndex(idx) { // idx is 1-based pull index within current pity cycle if (pity > 0 && idx >= pity) return 1.0; // hard pity guarantees item if (softPity > 0 && idx >= softPity) { // Soft pity: rate increases linearly from baseRate to 1.0 between softPity and pity if (pity > 0 && softPity 0 ? softRate : baseRate; } return baseRate; }
// Step 2: Compute probability of exactly k successes in n pulls using DP // We track state: (pull_index_in_current_cycle, number_of_successes_so_far) // dp[s] = probability of having exactly s successes after processing pulls so far // We also track current position in pity cycle
// For efficiency, we use a DP where state = (pity_counter, successes) // pity_counter resets to 1 after each success // dp[pity_counter][successes] = probability
var maxSuccesses = desired + 1; // cap tracking at desired+1 // dp[p][s] = prob of being at pity counter p with s successes // p ranges 1..pity (or 1..numPulls if no pity) var maxPity = (pity > 0) ? pity : numPulls;
// Initialize: start at pity counter = 1, successes = 0 // Use flat arrays for performance var dpSize = (maxPity + 1) * (maxSuccesses + 1); var dp = new Float64Array(dpSize); var dpNext = new Float64Array(dpSize);
function idx(p, s) { return p * (maxSuccesses + 1) + s; }
dp[idx(1, 0)] = 1.0;
for (var pull = 0; pull 0 && p >= pity) ? 1 : p + 1; if (newP 0 && p >= pity) ? 1 : p + 1; if (newP2 = desired successes var probAtLeastDesired = 0; var probExact = new Array(maxSuccesses + 1).fill(0); for (var p2 = 1; p2 0 && pp >= pity) ? 1 : pp + 1; if (np ' + hi; while (lo = targetProb) hi = mid; else lo = mid + 1; } return lo; }
var pulls50 = pullsFor(0.5); var pulls90 = pullsFor(0.9);
var totalCost = isNaN(costPerPull) || costPerPull '; html += 'Probability of getting ≥' + desired + ' item(s) in ' + numPulls + ' pulls:' + pct + '%'; html += 'Expected pulls to get ' + desired + ' item(s):' + expStr + ' pulls'; html += 'Pulls needed for 50% chance:' + pulls50 + ' pulls'; html += 'Pulls needed for 90% chance:' + pulls90 + ' pulls'; if (totalCost !== null) { html += 'Expected cost (at ' + costPerPull + '/pull):' + totalCost.toFixed(2) + ' currency'; } html += '';
// Distribution breakdown html += 'Success Distribution (in ' + numPulls + ' pulls):'; html += ''; html += 'Items ObtainedProbability'; var showMax = Math.min(maxSuccesses, desired + 3); for (var d = 0; d = desired ? 'background:#eff6ff;' : ''; html += '' + label + '' + rowProb + '%'; } html += '';
document.getElementById('gac-result').innerHTML = html; }
#### Formula
Without Pity: P(at least 1 success in n pulls) = 1 − (1 − p)n
With Pity (general): Uses dynamic programming over the Markov chain of (pity_counter, successes_count). At each pull index i within a pity cycle:
- Base rate: p(i) = pbase for i < soft_pity_start
- Soft pity: p(i) = pbase + (1 − pbase) × (i − soft_pity_start) / (hard_pity − soft_pity_start) for soft_pity_start ≤ i < hard_pity
- Hard pity: p(i) = 1.0 at i = hard_pity (guaranteed)
Expected pulls per item: E = Σn=1pity n × P(first success on pull n) = Σ n × p(n) × Πk=1n−1(1 − p(k))
Expected pulls for k items: Etotal = k × E[pulls per item]
DP transition: dp[p+1][s] += dp[p][s] × (1 − p(p)); dp[1][s+1] += dp[p][s] × p(p)
#### Assumptions & References
More Calculators
- Storage & Preservation Cost Calculator
- Commercial Lease Space Build-Out Cost Calculator
- Compliance Audit Preparation Cost Calculator
- Grading vs. Raw Card ROI Calculator
- Colorado Contractor License Bond Amount Calculator
- GDPR Fine Risk Calculator
- Fence Material Calculator
- Debt Payoff Calculator
- Business Startup Cost Estimator
- Compound Interest Calculator
- Generator Runtime and Fuel Calculator
Read Next
Study Time Planner Authority Network America › Life Services Authority › National Calculator Authority .calc-container { max-width: 640px;...