Ability
A passive trait of a creature that changes a battle rule whenever it applies, with no action to trigger it.
On this page
Ruby and Sapphire give each species one or two of 77 abilities, and a Pokémon’s personality value picks between two1. An ability reaches into existing rules: Battle Armor blocks critical hits2, Levitate makes Ground moves miss3, and Run Away always escapes4.
- Pokémon Ruby and Sapphire (2002). 77 abilities, one or two per species, picked by the personality value.1,2,5
- Pokémon Emerald (2004). Levitate, Wonder Guard, Run Away, and the weather-speed abilities bend the rules they touch.3,6,7,8
Games
| Game | Year | How | Note |
|---|---|---|---|
| Pokémon Ruby and Sapphire | 2002 | 77 abilities, one or two per species, picked by the personality value | |
| Pokémon Emerald | 2004 | Levitate, Wonder Guard, Run Away, and the weather-speed abilities bend the rules they touch | |
| Pokémon Platinum | 2008 | Technician, Super Luck, Sniper, and Mold Breaker | |
| Pokémon HeartGold and SoulSilver | 2009 | lead-Pokémon abilities that double or halve the encounter rate, and the critical-hit abilities |
Every claim about this mechanic, by game (12)
References
- ^ abRuby and Sapphire define 77 abilities, from Stench (1) to Air Lock (77); a species lists one or two, and when it has two, the lowest bit of the Pokémon's personality value picks which.Codepret/pokeruby
How we know
4#define ABILITY_NONE 0 5#define ABILITY_STENCH 1 ⋮ 81#define ABILITY_AIR_LOCK 77 ⋮ 83#define ABILITIES_COUNT 78
include/constants/abilities.h lines 4–83 at 5784633 · upstream ↗ 1465 if (gBaseStats[species].ability2) ⋮ 1467 value = personality & 1; 1468 SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value);
src/pokemon_1.c lines 1465–1468 at 5784633 · upstream ↗ 1056u8 GetAbilityBySpecies(u16 species, bool8 altAbility) ⋮ 1058 if (altAbility) 1059 gLastUsedAbility = gBaseStats[species].ability2; 1060 else 1061 gLastUsedAbility = gBaseStats[species].ability1;
src/pokemon_2.c lines 1056–1063 at 5784633 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abRuby and Sapphire's
atk04_critcalc, which Emerald keeps apart from a renamed helper, sums Focus Energy (+2), a move whose effect is high-critical, Sky Attack, Blaze Kick, or Poison Tail (+1), a Scope Lens (+1), and Lucky Punch or Stick on their species (+2), caps the stage at 4, and hits critically 1 time in 16, 8, 4, 3, or 2. Battle Armor or Shell Armor on the target, theSTATUS3_CANT_SCORE_A_CRITflag on the attacker, Wally's tutorial, and the first battle rule it out.Codepret/pokeruby · pret/pokeemeraldrevisedHow we know
1387 critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) 1388 + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) 1389 + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) 1390 + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) 1391 + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) 1392 + (holdEffect == HOLD_EFFECT_SCOPE_LENS) ⋮ 1399 if ((gBattleMons[gBattlerTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBattlerTarget].ability != ABILITY_SHELL_ARMOR) 1400 && !(gStatuses3[gBattlerAttacker] & STATUS3_CANT_SCORE_A_CRIT) 1401 && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) 1402 && !(Random() % sCriticalHitChance[critChance]))
src/battle_script_commands.c lines 1387–1402 at 5784633 · upstream ↗ 822static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2};src/battle_script_commands.c line 822 at 5784633 · upstream ↗ 1253static void Cmd_critcalc(void)src/battle_script_commands.c lines 1253–1289 at 731ad5b · upstream ↗ 606static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2};src/battle_script_commands.c line 606 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ ab
Cmd_typecalcflags a Ground move against a Levitate target as missed and “doesn't affect”, and walks no type row.Codepret/pokeemeraldHow we know
1375 if (gBattleMons[gBattlerTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) ⋮ 1377 gLastUsedAbility = gBattleMons[gBattlerTarget].ability; 1378 gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);
src/battle_script_commands.c lines 1375–1384 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^Ruby and Sapphire's
TryRunFromBattlealways escapes with a Smoke Ball or Run Away; otherwise, in a single battle, a Pokémon at least as fast as the foe escapes, and a slower one when , for earlier tries, beats a random byte. Emerald adds only the Battle Pyramid's and Frontier's rules.Codepret/pokeruby · pret/pokeemeraldHow we know
5465 if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) ⋮ 5471 else if (gBattleMons[bank].ability == ABILITY_RUN_AWAY) ⋮ 5477 else ⋮ 5481 if (gBattleMons[bank].speed < gBattleMons[bank ^ BIT_SIDE].speed) ⋮ 5483 speedVar = (gBattleMons[bank].speed * 128) / (gBattleMons[bank ^ BIT_SIDE].speed) + (gBattleStruct->runTries * 30); 5484 if (speedVar > (Random() & 0xFF))
src/battle_main.c lines 5465–5490 at 5784633 · upstream ↗ src/battle_util.c#L407-L485 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In Ruby and Sapphire, rain, sandstorm, or drought on the overworld starts a battle in that weather with no turn limit, Drizzle sets lasting rain when its holder enters, and Cloud Nine or Air Lock on the field turns weather's effects off.Codepret/pokeruby
How we know
1794 case 0xFF: //weather from overworld 1795 switch (GetCurrentWeather()) ⋮ 1797 case WEATHER_RAIN_LIGHT: ⋮ 1802 gBattleWeather = (B_WEATHER_RAIN_TEMPORARY | B_WEATHER_RAIN_PERMANENT); ⋮ 1833 case ABILITY_DRIZZLE: 1834 if (!(gBattleWeather & B_WEATHER_RAIN_PERMANENT)) ⋮ 1836 gBattleWeather = (B_WEATHER_RAIN_PERMANENT | B_WEATHER_RAIN_TEMPORARY);
src/battle_util.c lines 1794–1836 at 5784633 · upstream ↗ 50#define WEATHER_HAS_EFFECT ((!AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_CLOUD_NINE, 0, 0) && !AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_AIR_LOCK, 0, 0)))include/battle_util.h line 50 at 5784633 · upstream ↗ 771 case ENDTURN_RAIN: 772 if (gBattleWeather & B_WEATHER_RAIN) ⋮ 774 if (!(gBattleWeather & B_WEATHER_RAIN_PERMANENT)) ⋮ 776 if (--gWishFutureKnock.weatherDuration == 0)
src/battle_util.c lines 771–776 at 5784633 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^After the rows, a Wonder Guard target makes a damaging move miss on the turn it attacks, unless the move carries the super-effective flag without the not-very-effective one.Codepret/pokeemerald
How we know
1409 if (gBattleMons[gBattlerTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBattlerAttacker, gCurrentMove) == 2 1410 && (!(gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || ((gMoveResultFlags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) 1411 && gBattleMoves[gCurrentMove].power)
src/battle_script_commands.c lines 1409–1419 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^
TryRunFromBattlealways escapes with a Smoke Ball, or with the Run Away ability outside the Battle Pyramid. Otherwise, in a single battle outside the Pyramid, it escapes when the player's Pokémon is at least as fast as the foe, or when , stored in a byte, exceeds a random byte, for earlier attempts.Codepret/pokeemeraldrevisedHow we know
412 u8 speedVar; ⋮ 416 else ⋮ 421 if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) ⋮ 425 effect++; ⋮ 427 else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY) ⋮ 429 if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE) ⋮ 431 gBattleStruct->runTries++; ⋮ 434 if (speedVar > (Random() & 0xFF)) ⋮ 438 effect++; ⋮ 441 else ⋮ 445 effect++; ⋮ 450 effect++; ⋮
src/battle_util.c lines 407–475 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Revised after a check by a second AI model, 2026-10-21: The run formula holds only in single battles outside the Battle Pyramid.
- ^
GetWhoStrikesFirstputs the higher-priority move first; at equal priority the higher Speed goes first, after stat stages, Swift Swim or Chlorophyll in their weather, the third badge's ×1.1 for the player, Macho Brace, paralysis's ×¼, and a Quick Claw that triggers; a tie is a coin flip.Codepret/pokeemeraldHow we know
4595u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves) ⋮ 4609 else ⋮ 4615 else ⋮ 4618 else ⋮ 4633 else ⋮ 4644 speedBattler1 = (speedBattler1 * 110) / 100; ⋮ 4650 if (gBattleMons[battler1].status1 & STATUS1_PARALYSIS) 4651 speedBattler1 /= 4; ⋮ 4653 if (holdEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * holdEffectParam) / 100) 4654 speedBattler1 = UINT_MAX; ⋮ 4667 else ⋮ 4687 if (holdEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * holdEffectParam) / 100) ⋮
src/battle_main.c lines 4595–4750 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
Sources
Code
- pret contributors. 2026. “pokeruby: decompilation of Pokémon Ruby and Sapphire.” pret. Commit 5784633. pret/pokeruby @ 5784633 · licence, all uses
- pret contributors. 2026. “pokeemerald: decompilation of Pokémon Emerald.” pret. Commit 731ad5b. pret/pokeemerald @ 731ad5b · licence, all uses