I was working on an arena-based hack for FE8, when I accidentally triggered the infamous “unused” super arena mode. Since my hack is based entirely around the arena and makes heavy modifications to it, it seemed pertinent to discover what was actually going on here. Here’s what I found.
There are 3 bits that are stored in each unit’s state that determine it’s “Arena Level”. This level goes up every time a unit enters an arena battle OR resumes one where they win. If a unit with an arena level of 5 or higher enters the arena, they’ll get opponents who are 7 autolevels higher.
However, the update occurs on the active unit AFTER the battle actor has already been generated. This is a problem because it should be updating the active unit’s battle actor and not the active unit itself. After leaving the arena, the game updates the active unit by copying the data from it’s battle actor back on to the active unit.
So here’s what the issue looks like:
1.Battle actor is generated from the active unit.
2.Active unit has it’s arena level increased.
3.Arena battle is fought and won
4.Leave the arena and return to map.
5.Battle actor(no arena level) is copied onto the active unit(had arena level).
So my take away from this is that the super arena might not actually have been cut content at all, but rather bugged so badly it can’t be accessed without using an exploit.
Changing a single byte fixes this entirely by having the arena level stored to the battle actor. Oops.
This has always been one of those things I never saw an explanation for. Is this same bug present in FE6 and 7, as well, and was simply never caught due to a fair bit of code being identical across the games?
Yup, although I doubt it was touched at all after the first release of FE7J.
I updated the post to include the relevent address for each version. In all cases, they is a str r1, [r6, 0Ch] instruction that can be changed into a str r1, [r5, 0Ch] by changing a single byte.
What really makes me think this is a bug is that why would they add a condition for resuming if they were going to store it to a permanent structure anyway? The battle actor isn’t saved and is regenerated every time the game resumes, so a condition for a temporary structure like that just makes sense.
Ironically, this doesn’t just fix the super arena not working, but also the reset exploit that allowed people to trigger it in the first place.
So I looked further into it and it turns out that this resume condition was originally added in FE6 to account for win-lose records. However, the record battle stats function is way more complex than just flipping a few bits on a character. That fuction comes with it’s own internal check for resuming, among other conditions.
Whoever added this arena level thing really didn’t test it well, because even when stored to the battle actor, there are still a ton of bugs. If you resume from a non-fatal combat round, you can avoid having your arena level increased at all. Also, backing out of the arena will still increase your arena level.
Here’s the code from the FE6 Decomp
if (!just_resumed || (gBattleUnitB.unit.hp == 0))
PidStatsUpdateFromBattleOutcome();
It at least fixes those 2 original bugs, but yeah it’s a mess. The check is only found in “BattleArenaGenerate”, which only covers the first round of arena combat (either directly from the fight menu, or resuming).
However, any additional combat rounds after that are handled by “ArenaContinueBattle”, which also has the win-lose check but is noticeably lacking the arena level part.
Notice how this section here looks like FE6 version, without the arena level increment.
if (!(resumedFlag) || (gBattleTarget.unit.curHP == 0)) {
PidStatsRecordBattleRes();
}
If I had programmed this myself, I would have put the arena level bits at the very end of the win-lose function, since their intent is so similar.
Basically, right after the part that records the win, add a check if you’re in the arena, then add the levels.
I went out of my way to track down where the byte for the above bugfix is located in the other versions. Here you go:
FE7E1(En,Fr,De): 0x02AD86
FE7E2(En,Es,It): 0x02AD82
FE8E: 0x02D1A6
Something funny I noticed is that at least the german localization(I didn’t bother looking at the other languages) does not have the text for the Super Arena fixed in FE7E1(Same scrolling visual issues as in english), but it DOES appearently have it fixed in FE8E. I have genuinely no idea why they would go out of their way to fix text that went unused since the previous game, but okie doki.
I’ll add the European ones to the main post for completeness sake. It’s interesting that the two FE7s are only off by 4 bytes.
I doubt anybody actually saw the super arena text in game during the localization process. Someone probably noticed the poor formating compared to the other arena dialogue and fixed it based on that.