*Calculations based on Generation VII (Sun/Moon/USUM) mechanics.
Understanding Catch Rates in Alola (Gen VII)
Capturing Pokémon in Generation VII games (Sun, Moon, Ultra Sun, and Ultra Moon) relies on a mathematical formula that determines whether a thrown Poké Ball will successfully contain the target. While luck plays a role, understanding the variables allows trainers to maximize their odds, especially when hunting Legendaries or Ultra Beasts.
The Gen VII Catch Formula
The core mechanic involves calculating a "Modified Catch Rate" (a), which is then compared against random numbers generated by the game to determine if the ball shakes and eventually clicks shut.
MaxHP & CurrHP: The lower the target's current HP relative to its maximum HP, the higher the catch rate. False Swipe is essential here to safely reduce HP to 1 without fainting the target.
Rate: The species-specific catch rate. A Pikipek has a rate of 255 (easy), while a Necrozma has a rate of 3 (difficult).
Ball: The multiplier of the Poké Ball used. A Quick Ball on the first turn (5x) is significantly better than a standard Poké Ball (1x).
Status: Status conditions provide a flat multiplier. Sleep and Freeze provide the highest bonus (2.5x), while Paralyze, Poison, and Burn provide 1.5x.
Shake Checks and Probability
Once the modified catch rate a is calculated, if it is less than 255, the game calculates a "shake probability" number b. The game then generates four random numbers between 0 and 65535. If all four numbers are less than b, the Pokémon is caught.
This calculator simulates that logic to give you the exact percentage chance of a successful capture per ball thrown. It also estimates the average number of balls you will need to use.
Tips for Success in Ultra Sun & Ultra Moon
Use Roto Catch: In USUM, the Roto Loto feature can grant Roto Catch, which boosts capture chances significantly.
Beast Balls on UBs: When catching Ultra Beasts like Nihilego or Buzzwole, always use Beast Balls (5x modifier). Conversely, do not use Beast Balls on regular Pokémon (0.1x modifier).
Status is Key: Always try to induce Sleep or Paralysis. Sleep offers a higher bonus but wears off; Paralysis is permanent but offers a lower bonus.
Turn Count: If a battle drags on (10+ turns), the Timer Ball becomes one of the most effective options available (4x modifier).
function calculateCatchRate() {
// 1. Get Input Values
var speciesRate = parseInt(document.getElementById('speciesRate').value);
var maxHp = parseInt(document.getElementById('maxHp').value);
var currHp = parseInt(document.getElementById('currHp').value);
var ballBonus = parseFloat(document.getElementById('ballBonus').value);
var statusBonus = parseFloat(document.getElementById('statusBonus').value);
// 2. Validation
if (isNaN(speciesRate) || isNaN(maxHp) || isNaN(currHp)) {
alert("Please enter valid numbers for HP and Catch Rate.");
return;
}
if (currHp > maxHp) {
alert("Current HP cannot be higher than Max HP.");
return;
}
if (currHp 255) a = 255;
if (a = 255) {
percentage = 100;
shakeCheckVal = 65536;
} else {
// Calculate 'b' (Shake Probability)
// Gen 7 Formula: b = 65536 * (a/255)^0.25
shakeCheckVal = Math.floor(65536 * Math.pow(a / 255, 0.25));
// Probability of passing one shake check = b / 65536
// Probability of passing 4 shake checks = (b / 65536)^4
var pSingle = shakeCheckVal / 65536;
percentage = Math.pow(pSingle, 4) * 100;
}
// 5. Balls Needed (Expected Value = 1 / Probability)
var balls = (percentage >= 100) ? 1 : (100 / percentage);
// 6. Display Results
displayResult(a, shakeCheckVal, percentage, balls);
}
function displayResult(a, b, percentage, balls) {
var resultDiv = document.getElementById('result');
var probDisplay = document.getElementById('finalProbDisplay');
var valADisplay = document.getElementById('valA');
var shakeDisplay = document.getElementById('shakeCheck');
var ballsDisplay = document.getElementById('ballsNeeded');
// Format
var finalPercent = percentage >= 100 ? 100 : percentage.toFixed(2);
var displayBalls = balls > 1000 ? "> 1000" : balls.toFixed(1);
valADisplay.innerText = a;
shakeDisplay.innerText = b; // This corresponds to the 16-bit threshold
probDisplay.innerText = finalPercent + "%";
ballsDisplay.innerText = displayBalls;
// Visual coloring for probability
if (percentage >= 90) {
probDisplay.style.color = "#27ae60"; // Green
} else if (percentage >= 50) {
probDisplay.style.color = "#f39c12"; // Orange
} else {
probDisplay.style.color = "#c0392b"; // Red
}
resultDiv.style.display = "block";
}