data/claims/pokeruby.yamlPokémon Ruby and Sapphire (pret/pokeruby)
Game: Pokémon Ruby and Sapphire.
Ruby 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, the STATUS3_CANT_SCORE_A_CRIT flag on the attacker, Wally's tutorial, and the first battle rule it out. pokeruby/critical-chance
About: Pokémon Ruby and Sapphire Critical hit
Value
{
"oneIn": [
16,
8,
4,
3,
2
]
}src/battle_script_commands.c#L1387-L1402critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0)
+ (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL)
+ (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK)
+ (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK)
+ (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL)
+ (holdEffect == HOLD_EFFECT_SCOPE_LENS)
…
if ((gBattleMons[gBattlerTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBattlerTarget].ability != ABILITY_SHELL_ARMOR)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_CANT_SCORE_A_CRIT)
&& !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
&& !(Random() % sCriticalHitChance[critChance]))pokeruby: decompilation of Pokémon Ruby and Sapphire · src/battle_script_commands.c#L822-L822static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2};pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L1253-L1289static void Cmd_critcalc(void)pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L606-L606static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2};Checked by claude-agent, 2026-10-21 — read atk04_critcalc (L1373–L1408) and the table at the pokeruby pin, and diffed the function against pokeemerald's Cmd_critcalc with battler names normalized; the only differing line is the hold-effect helper's name, and the tables match.Cited by: Ability, Critical hit, Pokémon Ruby and Sapphire
Ruby and Sapphire's atk01_accuracycheck, which Emerald keeps with renamed constants, scales a move's percent accuracy by one combined stage ratio, applies Compound Eyes (×1.3), Sand Veil in a sandstorm and Hustle on physical moves (×0.8 each), and a target's evasion item, and misses when a roll from 1 to 100 exceeds the result. pokeruby/hit-test
About: Pokémon Ruby and Sapphire Hit chance
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_script_commands.c#L1272-L1299calc = gAccuracyStageRatios[buff].dividend * moveAcc;
calc /= gAccuracyStageRatios[buff].divisor;
…
calc = (calc * 130) / 100; // 1.3 compound eyes boost
…
calc = (calc * 80) / 100; // 1.2 sand veil loss;
…
calc = (calc * 80) / 100; // 1.2 hustle loss;
…
calc = (calc * (100 - quality)) / 100;
…
if ((Random() % 100 + 1) > calc)pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L1099-L1252 — Emerald's Cmd_accuracycheck; the diff shows named constants for Ruby's literals and nothing else of substance.Checked by claude-agent, 2026-10-21 — read the lines at the pokeruby pin and diffed the function against pokeemerald's with names normalized; `type < 9` in Ruby's Hustle check is Emerald's IS_TYPE_PHYSICAL.Cited by: Hit chance, Pokémon Ruby and Sapphire
Ruby and Sapphire's gTypeEffectiveness holds the same 110 rows as Emerald's and Crystal's, in the same order, with literal 0xFE and 0xFF bytes where Emerald names TYPE_FORESIGHT and TYPE_ENDTABLE. pokeruby/type-chart
About: Pokémon Ruby and Sapphire Type effectiveness
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·data/type_effectiveness.inc#L1-L119@ format: attacking type, defending type, damage multiplier
…
.byte 0xFE, 0xFE, 0
.byte TYPE_NORMAL, TYPE_GHOST, 0
.byte TYPE_FIGHTING, TYPE_GHOST, 0
.byte 0xFF, 0xFF, 0pokeemerald: decompilation of Pokémon Emerald · src/battle_main.c#L335-L449const u8 gTypeEffectiveness[336] =pokecrystal: disassembly of Pokémon Crystal · data/types/type_matchups.asm#L1-L118TypeMatchups:
…
db -2 ; end (with Foresight)Checked by claude-agent, 2026-10-21 — parsed the three tables at their pins with a script; Ruby's 110 rows equal Emerald's 112 entries less the two marker rows, and Crystal's 110 rows, in order (Crystal names Psychic `PSYCHIC_TYPE`).Cited by: Type effectiveness
Ruby and Sapphire's atk06_typecalc applies STAB as before the type rows, as Emerald's Cmd_typecalc does. pokeruby/stab
About: Pokémon Ruby and Sapphire Same-type attack bonus
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_script_commands.c#L1486-L1490//check stab
…
gBattleMoveDamage = gBattleMoveDamage * 15;pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L1368-L1372// check stab
if (IS_BATTLER_OF_TYPE(gBattlerAttacker, moveType))
{
gBattleMoveDamage = gBattleMoveDamage * 15;
gBattleMoveDamage = gBattleMoveDamage / 10;Checked by claude-agent, 2026-10-21 — read the STAB lines in both pins and diffed atk06_typecalc against pokeemerald's Cmd_typecalc; the STAB arithmetic matches.Cited by: Same-type attack bonus
Ruby and Sapphire already use Emerald's random factor, damage × (100 − rand % 16) / 100, raised to 1 if that gives 0; Gen 1 and 2 reach about the same 85–100% spread as a byte from 217 to 255 over 255. pokeruby/random-factor
About: Pokémon Ruby and Sapphire Damage formula
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_script_commands.c#L1751-L1763static inline void ApplyRandomDmgMultiplier(void)
{
u16 rand = Random();
u16 randPercent = 100 - (rand % 16);
…
gBattleMoveDamage *= randPercent;
gBattleMoveDamage /= 100;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L1639-L1651static inline void ApplyRandomDmgMultiplier(void)
{
u16 rand = Random();
u16 randPercent = 100 - (rand % 16);Checked by claude-agent, 2026-10-21 — read both functions at their pins; atk07_adjustnormaldamage calls Ruby's at L1774. The Gen 1–2 range is pokered/random-factor and pokegold/damage-variation.Cited by: Damage formula, Pokémon Ruby and Sapphire
Ruby and Sapphire's atk8D_setmultihitcounter gives 2 or 3 hits with probability 3/8 each and 4 or 5 with 1/8 each, the same code as Emerald's; the multi-hit battle script runs accuracycheck once and then loops critcalc, damagecalc, and adjustnormaldamage for every hit. pokeruby/multi-hit
About: Pokémon Ruby and Sapphire Multi-hit attack
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_script_commands.c#L6697-L6710gMultiHitCounter = Random() & 3;
if (gMultiHitCounter > 1)
gMultiHitCounter = (Random() & 3) + 2;
else
gMultiHitCounter += 2;pokeruby: decompilation of Pokémon Ruby and Sapphire · data/battle_scripts_1.s#L652-L690BattleScript_EffectMultiHit: @ 81D72ED
…
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
…
setmultihitcounter 0
…
BattleScript_MultiHitLoop: @ 81D7300
…
critcalc
damagecalc
…
adjustnormaldamage
…pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L7139-L7155static void Cmd_setmultihitcounter(void)Checked by claude-agent, 2026-10-21 — read the function and the multi-hit script at the pokeruby pin, and diffed the function against pokeemerald's Cmd_setmultihitcounter; only the read of the script byte is written differently.Cited by: Multi-hit attack
Ruby and Sapphire multiply the area's encounter rate by 16, cut it to 80% on the Mach or Acro Bike, apply the flute and Cleanse Tag modifiers, halve it for a lead with Stench and double it for Illuminate, cap it at 2,880, and start a battle when Random() % 2880 is below it. Emerald keeps the roll and adds more ability modifiers. pokeruby/encounter-rate
About: Pokémon Ruby and Sapphire Random encounter
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/wild_encounter.c#L21-L21#define MAX_ENCOUNTER_RATE 2880pokeruby: decompilation of Pokémon Ruby and Sapphire · src/wild_encounter.c#L377-L381static bool8 DoWildEncounterRateDiceRoll(u16 encounterRate)
{
if (Random() % MAX_ENCOUNTER_RATE < encounterRate)pokeruby: decompilation of Pokémon Ruby and Sapphire · src/wild_encounter.c#L403-L424static bool8 DoWildEncounterTest(u32 encounterRate, bool8 ignoreAbility)
{
encounterRate *= 16;
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
encounterRate = encounterRate * 80 / 100;
ApplyFluteEncounterRateMod(&encounterRate);
ApplyCleanseTagEncounterRateMod(&encounterRate);
…
if (ability == ABILITY_STENCH)
encounterRate /= 2;
if (ability == ABILITY_ILLUMINATE)
encounterRate *= 2;
…pokeemerald: decompilation of Pokémon Emerald · src/wild_encounter.c#L495-L527if (Random() % MAX_ENCOUNTER_RATE < encounterRate)
…
if (encounterRate > MAX_ENCOUNTER_RATE)
encounterRate = MAX_ENCOUNTER_RATE;Checked by claude-agent, 2026-10-21 — read the define, DoWildEncounterRateDiceRoll, and DoWildEncounterTest at the pokeruby pin, and Emerald's dice roll and WildEncounterCheck (L502–L527), whose ability block names more abilities than Ruby's two.Cited by: Random encounter
Ruby and Sapphire's TryRunFromBattle always 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. pokeruby/run
About: Pokémon Ruby and Sapphire Fleeing
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_main.c#L5465-L5490if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
…
else if (gBattleMons[bank].ability == ABILITY_RUN_AWAY)
…
if (gBattleMons[bank].speed < gBattleMons[bank ^ BIT_SIDE].speed)
{
speedVar = (gBattleMons[bank].speed * 128) / (gBattleMons[bank ^ BIT_SIDE].speed) + (gBattleStruct->runTries * 30);
if (speedVar > (Random() & 0xFF))pokeemerald: decompilation of Pokémon Emerald · src/battle_util.c#L407-L485 — Emerald's version, which adds the Battle Pyramid multiplier and Frontier checks.Checked by claude-agent, 2026-10-21 — read the function at the pokeruby pin and diffed it against pokeemerald's; the differences are the Pyramid and Frontier branches.Cited by: Ability, Fleeing, Pokémon Ruby and Sapphire
Ruby and Sapphire's GetWhoStrikesFirst puts the higher-priority move first; at equal priority the higher adjusted Speed goes first, and a tie is a coin flip. Adjusted Speed applies stat stages, doubles for Swift Swim in rain or Chlorophyll in sun, takes ×1.1 for the player's Pokémon with the third badge outside link battles, halves with a Macho Brace, and quarters under paralysis; a held Quick Claw sets it to the maximum when a per-turn random number is below its parameter, 20, as a percent of 0xFFFF. pokeruby/turn-order
About: Pokémon Ruby and Sapphire Turn order
Value
{
"quickClawPercent": 20
}src/battle_main.c#L4594-L4641// Check for abilities that boost speed in weather.
…
bank1SpeedMultiplier = 2;
…
// Calculate adjusted speed for first mon.
bank1AdjustedSpeed = (gBattleMons[bank1].speed * bank1SpeedMultiplier)
* gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][0] / gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][1];
…
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && FlagGet(FLAG_BADGE03_GET) && GetBattlerSide(bank1) == 0)
bank1AdjustedSpeed = (bank1AdjustedSpeed * 110) / 100;
if (heldItemEffect == HOLD_EFFECT_MACHO_BRACE)
bank1AdjustedSpeed /= 2;
…pokeruby: decompilation of Pokémon Ruby and Sapphire · src/battle_main.c#L4701-L4718if (gBattleMoves[bank1Move].priority != 0 || gBattleMoves[bank2Move].priority != 0)
{
if (gBattleMoves[bank1Move].priority == gBattleMoves[bank2Move].priority)
{
if (bank1AdjustedSpeed == bank2AdjustedSpeed && (Random() & 1))
strikesFirst = 2;
else if (bank1AdjustedSpeed < bank2AdjustedSpeed)
strikesFirst = 1;pokeruby: decompilation of Pokémon Ruby and Sapphire · src/data/items_en.h#L2932-L2936.name = _("QUICK CLAW"),
…
.holdEffect = HOLD_EFFECT_QUICK_CLAW,
.holdEffectParam = 20,Checked by claude-agent, 2026-10-21 — read GetWhoStrikesFirst (L4584–L4720) and the Quick Claw record at the pokeruby pin; the second battler's block (L4643–L4671) mirrors the first. Gold's Quick Claw is 60 in 256 (pokegold/turn-order).Cited by: Held item, Turn order
Ruby 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. pokeruby/abilities
About: Pokémon Ruby and Sapphire Ability
Value
{
"count": 77
}include/constants/abilities.h#L4-L83#define ABILITY_NONE 0
#define ABILITY_STENCH 1
…
#define ABILITY_AIR_LOCK 77
#define ABILITIES_COUNT 78pokeruby: decompilation of Pokémon Ruby and Sapphire · src/pokemon_1.c#L1465-L1468if (gBaseStats[species].ability2)
{
value = personality & 1;
SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value);pokeruby: decompilation of Pokémon Ruby and Sapphire · src/pokemon_2.c#L1056-L1063u8 GetAbilityBySpecies(u16 species, bool8 altAbility)
{
if (altAbility)
gLastUsedAbility = gBaseStats[species].ability2;
else
gLastUsedAbility = gBaseStats[species].ability1;Checked by claude-agent, 2026-10-21 — read the constants and the two functions at the pokeruby pin.Cited by: Ability, Pokémon Ruby and Sapphire
A Ruby and Sapphire Pokémon's nature is its personality value mod 25; each of the 25 raises one stat other than HP by 10% and lowers another by 10%, rounded down, except Hardy, Docile, Serious, Bashful, and Quirky, which change nothing. pokeruby/natures
About: Pokémon Ruby and Sapphire Nature
Value
{
"count": 25,
"up": 1.1,
"down": 0.9
}src/pokemon_3.c#L261-L264u8 GetNatureFromPersonality(u32 personality)
{
return personality % 25;pokeruby: decompilation of Pokémon Ruby and Sapphire · src/pokemon_3.c#L627-L657u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex)
…
switch (gNatureStatTable[nature][statIndex - 1])
{
case 1:
return (u16)(n * 110) / 100;
case -1:
return (u16)(n * 90) / 100;pokeruby: decompilation of Pokémon Ruby and Sapphire · src/pokemon_1.c#L1285-L1313const s8 gNatureStatTable[][5] =
{
// Atk Def Spd Sp.Atk Sp.Def
{ 0, 0, 0, 0, 0}, // Hardy
{ +1, -1, 0, 0, 0}, // LonelyChecked by claude-agent, 2026-10-21 — read the two functions and all 25 table rows at the pokeruby pin; the five all-zero rows are Hardy, Docile, Serious, Bashful, and Quirky.Cited by: Nature, Pokémon Ruby and Sapphire
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. pokeruby/weather
About: Pokémon Ruby and Sapphire Weather
Codepokeruby: decompilation of Pokémon Ruby and Sapphire ·src/battle_util.c#L1794-L1836case 0xFF: //weather from overworld
switch (GetCurrentWeather())
{
case WEATHER_RAIN_LIGHT:
…
gBattleWeather = (B_WEATHER_RAIN_TEMPORARY | B_WEATHER_RAIN_PERMANENT);
…
case ABILITY_DRIZZLE:
if (!(gBattleWeather & B_WEATHER_RAIN_PERMANENT))
{
gBattleWeather = (B_WEATHER_RAIN_PERMANENT | B_WEATHER_RAIN_TEMPORARY);pokeruby: decompilation of Pokémon Ruby and Sapphire · include/battle_util.h#L50-L50#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)))pokeruby: decompilation of Pokémon Ruby and Sapphire · src/battle_util.c#L771-L776case ENDTURN_RAIN:
if (gBattleWeather & B_WEATHER_RAIN)
{
if (!(gBattleWeather & B_WEATHER_RAIN_PERMANENT))
{
if (--gWishFutureKnock.weatherDuration == 0)Checked by claude-agent, 2026-10-21 — read the switch-in weather cases, the macro, and the end-of-turn rain case at the pokeruby pin; the countdown runs only without the PERMANENT flag.Cited by: Pokémon Ruby and Sapphire, Weather