Cite as
pret/pokeplatinum
Original
https://github.com/pret/pokeplatinum
Pinned
pret/pokeplatinum @ 49f78f35ccd8c6880e189d23a630eef2976c44ac
Accessed
2026-10-22
Licence
none stated (no LICENSE file; GitHub reports no license)
Credit
The pret community, about 79 GitHub contributors (2026-10-22), led in commit count by lhearachel, Fexty12573, gensarde, ravepossum and AsparagusEduardo. See https://github.com/pret/pokeplatinum/graphs/contributors.
Notes
A work-in-progress decompilation (README) that builds the US Platinum ROM, Rev 1 sha1 0862ec35b24de5c7e2dcb88c9eea0873110d755c and Rev 0 sha1 ce81046eda7d232513069519cb2085349896dec7. The battle engine (src/battle/) is C; src/ and include/ hold no NONMATCHING markers, and the only revision conditional (POKEPLATINUM_REVISION) is in the GTS screens, so the battle code reads the same for both revisions. Function and variable names are the decompilers', not Game Freak's.

Cited on

Claims (12)

HeartGold and SoulSilver (the US releases, which share this code) split the clock's hour into five periods with a 24-entry table: morning from 4:00 to 9:59, day from 10:00 to 16:59, evening from 17:00 to 19:59, night from 20:00 to 23:59, and late night from 0:00 to 3:59. Platinum's table gives every hour the same period (its names are morning, day, twilight, night, and late night). Gold and Silver have three periods: morning from 4:00, day from 10:00, and night from 18:00.src/rtc.c L153–183Code
When a step ends on grass or water, HeartGold and SoulSilver roll twice, each LCRandom() % 100. The first roll must fall below a gate that starts at 40, loses 20 unless the player is cycling or surfing or an unnamed avatar check (sub_0205DE98, still assembly) passes, gains 40 in very tall grass or else 30 when cycling, gains 30, 40, or 60 once a counter of reversed facings (reverseTurnFrameSteps) reaches 2, 3, or 4, and gains or loses 25 for the Pokémon March or the Pokémon Lullaby on the radio, capped at 100. The second must fall below the map's own rate for that terrain, capped at 100. A check comes only once a step counter (encounterInhibitSteps), which a wild battle or a warp clears, is past 3. Platinum's gate is 40, plus 30 in very tall grass or when cycling, adjusted on special dates, with no walking penalty, facing counter, or radio. Before its gate, Platinum adds a grace roll: while its count of attempts is below 8−min⁡(⌊r/10⌋,8) for the rate r it is passed (computed), each attempt adds 1 to the count and goes on only if LCRNG_RandMod(100) is below 5; a comment says this covers the first attempts after each map transition or wild battle. HeartGold and SoulSilver's check has no such roll; they skip the check outright while the step counter is 3 or less.src/overlay006/wild_encounters.c L763–778src/overlay006/wild_encounters.c L750–761src/overlay006/wild_encounters.c L797–808Code
HeartGold and SoulSilver have 12 grass slots and 5 surfing slots, picked by one LCRandom() % 100 against bounds in EncounterSlot_WildMonSlotRoll_Land and EncounterSlot_WildMonSlotRoll_Surfing, so they come up 20, 20, 10, 10, 10, 10, 5, 5, 4, 4, 1, and 1 percent and 60, 30, 5, 4, and 1 percent (computed from the bounds). Platinum's GetGroundEncounterSlot and GetWaterEncounterSlot have the same bounds. Gold and Silver have 7 grass slots and 3 water slots, with cumulative bounds in GrassMonProbTable (30, 60, 80, 90, 95, 99, 100) and WaterMonProbTable (60, 90, 100), so 30, 30, 20, 10, 5, 4, and 1 percent and 60, 30, and 10 percent (computed from the differences).src/overlay006/wild_encounters.c L820–866Code
A HeartGold or SoulSilver map's encounter record holds one walking rate and three full species lists for its 12 grass slots, morning, day, and night, sharing one list of levels. Gold and Silver keep a separate grass rate for each time of day and three sets of 7 slots. Platinum keeps one 12-slot list and swaps only slots 2 and 3 for their day or night species outside the morning.src/overlay006/wild_encounters.c L181–193src/overlay006/wild_encounters.c L334Code
HeartGold and SoulSilver's BattleSystem_CalculateBallShakes keeps Platinum's capture math: a=⌊⌊Cm/10⌋(3M−2H)/3M⌋ for catch rate C, ball multiplier m in tenths, max HP M and current HP H, ×2 for sleep or freeze and ×15/10 for burn, paralysis, poison, or bad poison, a catch at once when a is 255 or more, and otherwise four 16-bit rolls each below ⌊1048560/⌊16711680/a⌋⌋, with the Master Ball's shakes set to four after the draw. The Ultra, Great, Poké, and Safari Balls keep Platinum's 20, 15, 10, and 15 (an assembly data table in the decompilation), and a Pal Park or tutorial battle always catches.src/battle/battle_script.c L10978–10988src/battle/battle_script.c L10990–11013src/battle/battle_script.c L10868–10873Code
HeartGold and SoulSilver's TryCriticalHit keeps Platinum's critical-hit rule: the stage sum (+2 Focus Energy, +1 for a HOLD_EFFECT_CRITRATE_UP item, +1 Super Luck, +2 for Chansey or Farfetch'd with its own item, plus the move's boosts) capped at 4, a chance of 1 in 16, 8, 4, 3, or 2, blocked by Battle Armor or Shell Armor unless ignored, by Lucky Chant on the target's side, or by bit 15 of the target's move-effect flags (named MOVE_EFFECT_FLAG_LUCKY_CHANT here), and Sniper turning ×2 into ×3.src/battle/battle_lib.c L7096–7103src/battle/battle_lib.c L7123–7139include/constants/battle/moves.h L23src/battle/battle_lib.c L7142–7143Code
In Platinum the damage formula reads each move's own class (MOVE_DATA(move).class: CLASS_PHYSICAL, CLASS_SPECIAL, or CLASS_STATUS) and uses Attack against Defense for a physical move, Special Attack against Special Defense for a special one, whatever the move's type. Emerald picks the pair by type, below or above TYPE_MYSTERY in the type list, so Thunder Punch (Electric) is special in Emerald and physical in Platinum, and Shadow Ball (Ghost) is physical in Emerald and special in Platinum.include/move_table.h L12–15generated/move_classes.txt L1–3src/battle/battle_lib.c L6635–6638src/battle/battle_lib.c L6704src/battle/battle_lib.c L6947–6992res/moves/thunder_punch/data.json L10–11res/moves/shadow_ball/data.json L10–11Code
BattleSystem_CalcCriticalMulti keeps Emerald's stage table, 1 in 16, 8, 4, 3, or 2, capped at stage 4, and its sum: +2 for Focus Energy, +1 for a held item with HOLD_EFFECT_CRITRATE_UP, +2 for Chansey or Farfetch'd holding an item whose hold effect names that species, plus the move's boosts, which in Platinum come from a battle-script variable (criticalBoosts) rather than a list of move effects. It adds +1 for the ability Super Luck, which Emerald's sum doesn't read. Besides Battle Armor and Shell Armor, which an attacker with Mold Breaker ignores, Lucky Chant on the target's side blocks a critical, and so does a MOVE_EFFECT_NO_CRITICAL flag that a comment in the header says is checked but never set. Platinum draws its 16-bit roll before those tests, where Emerald draws it only after its other tests pass.src/battle/battle_lib.c L7096–7103src/battle/battle_lib.c L7123–7139src/battle/battle_lib.c L3112–3115src/battle/battle_script.c L2158–2162src/battle/battle_script.c L9531–9532include/constants/battle/moves.h L23src/battle/battle_system.c L1308–1312Code
A critical multiplies Platinum's damage by 2 after the base formula (its +2 included), at the same step as Emerald, and by 3 when the attacker has Sniper; Emerald's multiplier has no such case. As in Emerald, the critical then ignores the attacker's lowered attacking stat, the defender's raised defending stat, and Reflect or Light Screen.src/battle/battle_lib.c L7142–7146src/battle/battle_script.c L1334–1344src/battle/battle_lib.c L6947–7024src/battle/battle_lib.c L7078Code
Platinum's BattleScript_CalcCatchShakes keeps Emerald's capture math: the same a=⌊⌊Cm/10⌋(3M−2H)/3M⌋, the same status bonuses (×2 for sleep or freeze; ×15/10 for poison, bad poison, burn, or paralysis), a catch at once when a is 255 or more, and otherwise the threshold b=⌊1048560/⌊16711680/a⌋⌋ with up to four 16-bit rolls, each below b a shake, and the Master Ball's shakes set to four after the draw. The two square roots run on the DS hardware square-root unit (CP_SetSqrt32) instead of Emerald's GBA BIOS call, and both games roll with the same generator, multiplier 1,103,515,245 and increment 24,691, keeping the top 16 bits. A Pal Park battle or the catching tutorial always catches.src/battle/battle_script.c L10904–10907include/constants/battle.h L56src/battle/battle_script.c L10978–10988src/battle/battle_script.c L10990–11013include/constants/battle/battle_script.h L8src/battle/battle_system.c L1308–1312include/math_util.h L8–10Code
Platinum keeps Emerald's ball multipliers in tenths (Ultra 20, Great and Safari 15, Poké 10; Net 30 against Water or Bug, Nest 40 less the level below 40 with a floor of 10, Repeat 30, Timer 10 plus the turn count up to 40) and Emerald's 10 for the Luxury and Premier Balls. Two balls have new multipliers: a Dusk Ball gives 35 at night, late at night, or on cave terrain, and a Quick Ball 40 while the battle's turn count (totalTurns) is 0. The Dive Ball's 35 now asks for water terrain (TERRAIN_WATER) where Emerald asks for an underwater map. A Safari Ball multiplies the catch rate by one of 13 fractions from 10/40 to 40/10, picked by a stage that starts at 6 (×1), where Emerald uses a Safari catch factor. The Heal and Cherish Balls, also new, give 10.src/battle/battle_script.c L10868–10889src/battle/battle_script.c L10910–10975src/battle/battle_lib.c L2036generated/items.txt L1–17Code
In Platinum the ability Technician multiplies a move's power by 15/10 (rounded down) when that power is 60 or less, Struggle excepted. The test reads the power after the battle's power multiplier, Charge, and Helping Hand have changed it.src/battle/battle_lib.c L6687–6702Code