Suikoden II Bug: Castle Armory Bug
After the player recruits Hans, an Armor Shop becomes a part of the castle complex. Unlike other armor shops in the game, you have the option here of buying and equipping armor to characters not in your party, straight from the menu. This handy feature also comes with an exploitable bug that will give the player large amounts of potch when triggered.
Taking advantage of the bug requires a bit of effort. Characters must be equipped properly, and potch must be within a particular range. Below are the most common steps for the exploit.
- Remove the armor from, or strip a minimum of two characters who can wear the same armor as the Hero.
- Equip the Hero with the armor you intend to buy. Typically, Dragon Armor is used.
- Make sure the party's potch supply is just slightly more than enough to buy one of the item above. Dragon Armor costs 23,000 potch, so a range of 23,000 to 30,000 is advised.
- Go into the Armory and choose to buy Dragon Armor.
- When asked what to do with it, choose "Equip".
- Select the Hero as the character to equip the armor.
- The game will ask what to do with the armor the Hero is already wearing. You will have the option of putting it in the bag, or selling it. Instead, press the cancel button, and back up one menu.
- The game will again ask who to equip the purchase to. Choose one of the characters you stripped (the armor slot must be empty).
- After equipping, the game will not back out to the purchase menu, and instead allows you to continue selecting people to equip the purchase to. The potch display will not have updated after your last purchase.
- Choose the other character you stripped. The armor will be purchased and equipped. (You can optionally continue equipping the same armor to more characters, if you wish. Note that if you select one who has armor, you will have to choose what to do with it, and selecting either option on that screen will end the exploit.)
- Cancel out of the Equip menu (or buy another set and put it on someone who has armor). When the game drops you back to the purchase menu, you will have far more potch than you started with. If you don't equip more than the two characters you stripped for the purpose, you should have 999,999 potch.
Affected Versions
The North American and Japanese versions are affected by this bug. It was removed before the game was released in Europe.
Cause
This bug has a combination of causes and effects. The only permanent effect is the extra potch.
Firstly, the game uses a single, multipurpose routine for managing the party's potch. Depending upon the first argument supplied to it, the routine will retrieve the current potch amount, add (or subtract) potch, or set the potch variable to a particular value. This routine does not take into account the possibility that subtraction may result in the potch variable having a value less than zero. Behavior of this sort is safe, but it assumes that calling routines will not try to subtract 23,000 when the party only has 7,000 potch. When the potch variable underflows, it appears to be an extremely large positive value, and the management routine sets it to 999,999.
Secondly, while you are in the Equip menu, the shop's programming believes that the prices has already been checked. Normal behavior in this menu would be to back up to the Purchase menu after equipping once, but when the player backs out of the Bag/Sell selection in step 7, the menu mangles its own state. As long as the armor is then equipped to characters who are not wearing something else, the game will allow the purchase and will stay on the Equip screen. Since the price is not compared to the potch the party has, additional purchases can be made. Each additional purchase will subtract more potch.
- At the beginning of the exploit, the party has 25,000 potch on hand.
- In the purchase menu, 25,000 is compared to the 23,000 cost of Dragon Armor. The purchase can proceed.
- After backing out of the Bag/Sell option, the armor is equipped to someone naked. Potch is now 2,000.
- The game doesn't check potch, and allows an additional purchase to be made. Potch is now -23,000 (0xFFFFA628). The game doesn't handle potch as a signed value, so this appears to it to be over 4 billion potch. It sets it back to the maximum allowed, 999,999.
The code responsible for this is in
/CDROM/140_HONP/HDOUGUYA.BIN. The amount of code involved is extensive, and will not be covered here. The Potch Management routine is in the main executable (name varies by region).
Fix
The designers probably intended for the game to go back to the purchase menu normally after equipping like this.
I actually like having the ability to make multiple purchase of the same item, without having to select it again, so the fix chosen was to make that part of the menu check the price against current potch. The purchase will be rejected when not enough money is available, and the potch display is updated when purchases are successful.
During testing an alternative method was discovered for triggering the bug with only two characters. This method could even bypass the fix. As such, the solution of dropping back to the shop's inventory when cancelling at that point was determined to be the most effective fix. It's a one line code change. The fix described below is no longer used, and is retained for informational purposes only.
Below is the assembly code inserted for the (old and obsolete) fix. A large chunk of one routine was rewritten to insert the fix and make room for it.
.createfile armory_fix.bin, 0x80116F68
lw s0, 0x2C(s2)
jal 0x80072E58 ;get potch
addiu a0, zero, 0 ;
subu v1, zero, s0 ;negu cost (makes positive)
slt v1, v0, v1 ;potch < cost?
beq v1, zero, npotch
lui s1, 0x8012 ;important (for equipping purchase)
jal 0x800AF704 ;quack noise
addiu a0, zero, 0x500 ;sound idx
beq zero, zero, exit ;purchase cancelled
nop
npotch: jal 0x800AF704 ;cash register
addiu a0, zero, 0x50A ;sound idx
addiu a0, zero, 1 ;set arg to "add potch"
jal 0x80072E58 ;potch manage
addu a1, zero, s0 ;load cost (negative)
lbu a2, 0xC(s2)
lbu v1, 0x11(s2)
lw a1, 0x1D8(s2)
sll a2, a2, 2
addu a2, s2, a2
sll v1, v1, 2
addu v1, v1, a1
lb a1, 4(s2)
lbu a2, 0x34(a2)
lbu a3, 0(v1)
lbu v1, 1(v1)
addiu a0, s1, 0x96E0 ;important (for equipping purchase)
sw zero, 0x14(sp)
sw zero, 0x18(sp)
addiu a1, a1, 1
jal 0x8006E334
sw v1, 0x10(sp)
lbu v0, 6(s2)
addiu s1, zero, 1
bne v0, s1, skipb
lui v0, 0x8008 ; not necessary
lbu v1, 0x11(s2)
nop
sll v1, v1, 2
addu v1, s2, v1
lbu v0, 0x1DE(v1)
nop
addiu v0, v0, 0xFFFF
sb v0, 0x1DE(v1)
skipb:
jal 0x8008DBA8
lw a0, 0x18C(s2)
lw v1, 0x364(s2)
lw a0, 0x18C(s2)
lw v1, 0xC(v1)
addu a2, zero, zero
jal 0x8008D390
lw a1, 0x10(v1)
addiu v0, zero, 0x14
sb v0, 7(s2)
sb s1, 9(s2) ; call 0x8008DE94 to update potch display?
j 0x801243F4
nop
return_hack:
nop
nop
nop
nop
exit:
lui v0, 0xd00d ; dummy
.close
; time to code-cave it. I could keep making space by reworking the code, but yeesh.
.createfile armory_fix_diplay.bin, 0x801243F4
addiu a1, zero, 0
lw a0, 0x1CC(s2)
jal 0x8008DB48
addu a2, zero, a1
jal 0x80072E58
addiu a0, zero, 0
addu a1, zero, v0
lw a0, 0x1CC(s2)
jal 0x8008DE94
addiu a2, zero, 0x6
j return_hack
.close
GameShark Codes
This bug is easily avoided. No codes are needed, and they would be impossibly long in any case.
Patch
Find your version on the
Patch Files page.