Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of an article from Glitch City Laboratories wiki.

A live version of this article is available at the Glitch City Wiki here.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of the wiki in .tar.gz or .xml.gz formats.

Special Defense badge boost glitch

The Special Defense badge boost glitch is a glitch in Pokémon Gold, Silver and Crystal that causes the Glacier Badge's boost to the Special Defense stat of a Pokémon to not apply if the Special Attack stat of that Pokémon is in certain ranges.

Specifically, if the unboosted Special Attack stat (which may include the Special Attack stage modifier) is either 0 ~ 205, or 433 ~ 660, then the glitch will cause the player to lose the Special Defense boost.

After giving the player the Glacier Badge, Pryce mentions that "That BADGE will raise the SPECIAL stats of POKéMON." Presumably, the developer's intention is for the Glacier Badge to boost both the Special Attack and the Special Defence unconditionally. However, the code to apply the Special Defense boost uses register a to determine whether the boost should be applied, but the value in register a is overwritten while applying the Special Attack boost. This results in an unintended extra condition for the boost to apply.

Analysis

The piece of code to apply the badge stat boosts is as follows: (external link)

; The value in register b has been initialized to a bitmask for Johto badges, ; in the following order, starting from the least significant bit: ; ZEPHYR, HIVE, MINERAL, FOG, PLAIN, STORM, GLACIER, RISING. ; The order of the stats are: ; Attack, Defense, Speed, SpAtk, SpDef. ld hl, wBattleMonAttack ld c, 4 ; The number of times the below loop should execute .CheckBadge: ld a, b ; Save the value of b, specifically for use after the loop srl b ; Shift b to the right, removing the least significant bit call c, BoostStat ; Apply the boost if the bit just removed is 1 inc hl inc hl ; Move to the next stat (stats are 2-byte integers)

srl b ; Throw away a bit from b (only check every other badge) dec c jr nz, .CheckBadge

srl a ; Check Glacier Badge again for Special Defense call c, BoostStat ret

The last check assumes that the value in register a comes from the ld a, b instruction from the last iteration of the loop. Since the srl b immediately after is a check for the Glacier Badge, the final srl a should be a check for the Glacier Badge, too.

However, this does not take into account that the function BoostStat actually overwrites register a. The code for that function is as follows: (external link)

BoostStat: ; Raise stat at hl by 1/8. ld a, [hli] ld d, a ; High byte of the stat ld e, [hl] ; Low byte of the stat srl d rr e ; Shift the 16-bit integer de to the right... srl d rr e ; ... srl d rr e ; ... three times (i.e. divide by 8) ld a, [hl] add e ld [hld], a ld a, [hl] adc d ld [hli], a ; Add de back into the stat at hl ; Cap at 999. ld a, [hld] ; Low byte of boosted stat sub LOW(MAX_STAT_VALUE) ld a, [hl] ; High byte of boosted stat sbc HIGH(MAX_STAT_VALUE) ret c ; If boosted stat is less than 999, return ld a, HIGH(MAX_STAT_VALUE) ld [hli], a ld a, LOW(MAX_STAT_VALUE) ld [hld], a ; Otherwise, set boosted stat to 999 ret

Here, the value of MAX_STAT_VALUE is 999 = 0x03E7.

There are therefore three cases for the srl a check:
  • If the player does not have the Glacier Badge, then the function BoostStat is not called, and the check works as intended. The Special Defense boost will not be applied.
  • If the player has the Glacier Badge, and the unboosted Special Attack is at least 888, then the boosted Special Attack would be at least 999, and the last few instructions in BoostStat will cap it at 999, setting register a to LOW(MAX_STAT_VALUE) = 0xE7 in the process. The srl a check will see that the least significant bit of 0xE7 is 1, so the Special Defense boost will be applied.
  • If the player has the Glacier Badge, and the unboosted Special Attack is less than 888, then the value left in register a will be the result of sbc HIGH(MAX_STAT_VALUE), i.e. the high byte of (boosted Special Attack - 999). The table below shows the possible values for that high byte:

    Unboosted SpAtkBoosted SpAtkBoosted SpAtk - 999Value left in aSpDef boost?
    0 ~ 2050 ~ 230-999 ~ -769 (0xFC19 ~ 0xFCFF)0xFCNo
    206 ~ 432231 ~ 486-768 ~ -513 (0xFD00 ~ 0xFDFF)0xFDYes
    433 ~ 660487 ~ 742-512 ~ -257 (0xFE00 ~ 0xFEFF)0xFENo
    661 ~ 887743 ~ 997-256 ~ -2 (0xFF00 ~ 0xFFFE)0xFFYes


    In conclusion, this glitch causes an unintended behavior only when the player has the Glacier Badge, and the unboosted Special Attack of the Pokémon in question is either 0 ~ 205, or 433 ~ 660. In those cases, the glitch causes the Special Defense boost to not apply.

    Categories