Before spending your Primogems, it is crucial to understand how the "pity system" works in Genshin Impact. Unlike standard probability, Genshin uses a system that guarantees rewards after a certain number of attempts.
Base Rate vs. Consolidated Rate
The base probability of pulling a 5-star character on any single wish is 0.6%. However, HoYoverse advertises a "consolidated rate" of 1.6%, which accounts for the guarantee systems explained below.
The Pity System: Soft vs. Hard
There are two critical thresholds in the character event banner:
Soft Pity (Pull 74): Starting at the 74th pull without a 5-star, the probability dramatically increases with every subsequent pull. Most players obtain their 5-star character between pulls 74 and 80.
Hard Pity (Pull 90): If you are incredibly unlucky and do not receive a 5-star character by the 89th pull, the 90th pull is guaranteed to be a 5-star character (100% chance).
The 50/50 Rule
When you see a gold light (5-star), it is not always the character featured on the banner image.
50/50 Chance: The first time you pull a 5-star, there is a 50% chance it is the featured character and a 50% chance it is a standard banner character (e.g., Qiqi, Diluc, Keqing).
Guaranteed: If you lose the 50/50 (get a standard character), your next 5-star pull is guaranteed to be the featured character. This status carries over between banners.
Use the calculator above to determine exactly how many Primogems or Intertwined Fates you need to reach these thresholds.
function calculateGenshinRates() {
// 1. Get Input Values
var currentPityInput = document.getElementById('currentPity');
var guaranteedSelect = document.getElementById('guaranteedStatus');
var primogemsInput = document.getElementById('primogems');
var fatesInput = document.getElementById('fates');
// 2. Parse values (handle NaN or empty)
var currentPity = parseInt(currentPityInput.value) || 0;
var isGuaranteed = guaranteedSelect.value === "100";
var primogems = parseInt(primogemsInput.value) || 0;
var fates = parseInt(fatesInput.value) || 0;
// Validation bounds
if (currentPity 89) currentPity = 89;
// 3. Perform Calculations
// Resource Conversion
var pullsFromPrimos = Math.floor(primogems / 160);
var totalPullsAvailable = fates + pullsFromPrimos;
var remainingPrimos = primogems % 160;
var primosNeededForNext = 160 – remainingPrimos;
// Pity Math
var hardPityCap = 90;
var softPityStart = 74;
var pullsToHardPity = hardPityCap – currentPity;
var pullsToSoftPity = softPityStart – currentPity;
if (pullsToSoftPity = maxPullsForFeatured) {
probabilityText = "100% Guaranteed Featured";
} else if (totalPullsAvailable >= pullsToHardPity && isGuaranteed) {
probabilityText = "100% Guaranteed Featured";
} else if (totalPullsAvailable >= pullsToHardPity && !isGuaranteed) {
probabilityText = "50/50 Coin Flip (Reaches Hard Pity)";
} else {
// Calculate rough odds
// Base chance 0.6%. Cumulative over N pulls.
// Simplified formula P = 1 – (0.994 ^ pulls).
// Note: This ignores soft pity ramp up for simplicity in text,
// but is accurate enough for "Low/Medium" estimation below 74.
var effectivePulls = totalPullsAvailable;
// Add current pity to effective pulls for estimation context
var simulatedPity = currentPity + totalPullsAvailable;
if (simulatedPity >= 80) {
probabilityText = "Very High (>90%)";
} else if (simulatedPity >= 74) {
probabilityText = "High (Soft Pity Reached)";
} else {
// simple math 1 – 0.994^N
var chance = 1 – Math.pow(0.994, totalPullsAvailable);
var pct = (chance * 100).toFixed(1);
probabilityText = pct + "% Chance (Approx)";
}
}
// 4. Update UI
document.getElementById('resultsArea').style.display = "block";
document.getElementById('resTotalPulls').innerText = totalPullsAvailable;
document.getElementById('resNextPullCost').innerText = primosNeededForNext + " Primogems";
// If already past soft pity
if (currentPity >= 74) {
document.getElementById('resSoftPity').innerText = "Reached (Rates Increased)";
document.getElementById('resSoftPity').style.color = "#e53e3e";
} else {
document.getElementById('resSoftPity').innerText = pullsToSoftPity;
document.getElementById('resSoftPity').style.color = "#2d3748";
}
document.getElementById('resHardPity').innerText = pullsToHardPity;
document.getElementById('resFeaturedCost').innerText = maxPullsForFeatured;
document.getElementById('resProbability').innerHTML = probabilityText;
// Update Pity Bar
var barPercentage = (currentPity / 90) * 100;
if (barPercentage > 100) barPercentage = 100;
document.getElementById('pityBar').style.width = barPercentage + "%";
}