An exploration into Gameboy Advance ROM hacking
ROM hacking is the process of modifying a ROM image (usually of a video game) to alter the game’s graphics, dialogue, levels, gameplay, and/or other elements.
Double Fine recently released an episode of “Devs Play” where Brandon goes about hacking the ROM of the first Legend of Zelda for NES. I thought it was really interesting and it inspired me to start poking around one of my favorite games, Fire Emblem: The Sacred Stones for the Gameboy Advance.
To start off, I loaded up a copy of the game in VisualBoyAdvance, a GBA emulator. Note: I had to run VBA through Wine because the Mac version of VBA doesn’t have the features we need to look into the emulated GBA’s memory.
I started up a new game and skipped past the opening cutscenes into the first level of the game where Eirika and Seth are fleeing to Frelia. Normally, the first level is a tutorial level that forces you to make certain choices. If we set the difficulty to “Hard”, the game won’t try and teach us how to play so we can move our characters, attack, and use items freely.
Before we start changing things, we need to figure out what variables we want to mess around with and where they exist in memory. As Brandon did in his video, we want to change a single variable and then try and find its location in memory. In Fire Emblem, the only variables that really change over the course of a battle are a unit’s current hitpoints and the durability of its items. We start the first level with an injured Seth with 13/30 HP and an item called a “vulnerary” that restores some HP. This seems like a good place to start. Before we use the item, we want to go to Cheats->Create.
This new window allows us to search through memory addresses by comparing the values at those addresses either to their previous value or a specific value. Previous being the value they had when you last opened the window — pretty shitty UX, I know. So, let’s hit the “Start” button and select “Specific Value”, “Equal to”, “Unsigned”, and enter 13 (Seth’s current HP) into the box at the bottom. Hit “Search” and you should see a whole bunch of memory addresses and their values show up. One of these addresses is where Seth’s current HP is stored.
An important thing to understand about this search window is that each time you search, it only runs the search on the results of the previous search. If you want to start from scratch, you have to click “Start” again. Make sure “Update values” is checked and click OK to return back to the game. Now, we’re going to use the vulnerary on Seth which should bring him up to 23 HP. Now we can re-open the search window and search for 23, bringing our massive list of possibilities down to two addresses: 0x0202BE5F and 0x0203A4FF.
Now what we want to go to Tools->Memory Viewer. This allows us to see what exactly is in memory. Let’s go to the first address and see what’s there. Type in the first address (in hex, so as it’s written in the Search window) into the box at the top and hit GO. Unsurprisingly, we find the value 0x17 which when converted to decimal becomes 23.
Now, to test if this actually is the HP variable, let’s change it. Click on the value and change it to something else like 03. Now, click back on the game!
When you click back on the game, we should see Seth’s HP update to 3! Success! If it doesn’t, move the cursor off of Seth and then back on to him so that the game redraws his HP. (When the game redraws the screen, it will read the value at the address again.)
But, what about the other address? To make sure that this other address isn’t the real variable, we have to go to it and try changing it as well. If you go to 0x203A4FF and change it’s value, you’ll see it doesn’t have an effect on the game. I’m personally not sure what this variable is.
Now we know how to change Seth’s current HP. But what about all his other stats?
These stats change only change either when you level up or by using a special (and usually rare) item. When you level up, all your stats change at once but we also don’t want to wait until we get one of the rare stat boosting items. What can we do? In his video, Brandon discovers that all of the inventory items in Legend of Zelda are stored right next to each other.
Let’s imagine we’re the programmers of Fire Emblem and we have all these stats. How would we store them? We’d make a struct or an object to hold them!
Something like this:
So let’s try exploring what changing the nearby addresses will do. Let’s change the value at address 0x0202BE60 to 03 as well. Go back to the game and hit left and then right to redraw the screen.
Success! We’ve changed Seth’s strength variable. Now we can continue this trial and error process to figure out the addresses of the rest of his stats. I spent about 15 minutes trying out different addresses and came up with the following results:
But what about Eirika? In Fire Emblem, you can have quite a few characters in a given battle. Let’s assume everything is stored as an array of characters. If this is the case, then Eirika’s data should be right before or right after Seth’s. Let’s see if we can find Eirika’s data based on her stats. She has 16 max HP, 16 current HP, 4 Str, 8 Skill, and 9 Spd. For Seth, all of these stats were stored next to each other. So, let’s try and find the pattern 0x10 0x10 0x04 0x08 0x09 in memory. Unfortunately, the memory viewer doesn’t have a Ctrl-F function, so we’ll just have to look by hand.
There it is! If you try messing around with the data, you’ll see that the data is stored in the exact same format as Seth’s, just like we thought.
As you go further into the game, we can see that these addresses aren’t necessarily reserved for Seth or Eirika. In Fire Emblem, you can choose which characters you will take into a battle. There’s no need to load character data into memory if you aren’t going to use it, right?
Now this is where the fun begins!
We now know a lot of really useful stuff and can start messing around. Let’s change Seth’s first item to 0x35 and see what it does!
Seth now has a ballista! The ballista is not purchasable in game, only appears on certain levels, and can normally only be used by the Archer and Sniper classes (Seth is a Paladin). But, it seems the way this restriction is enforced is by giving the ballista a minimum weapon rank of E. Seth doesn’t have a bow weapon rank, meaning he can’t use even the most basic of bows. This also means he can never increase his bow weapon rank. I wonder what will happen when we manually increase Seth’s bow weapon rank?
Wow! Look at that crazy range! Ballistas aren’t the only items in the game that are locked like this. You can give any class almost any weapon, and as long as you change the right weapon level to be high enough, they can use it! Though, some might not have animations. For example, we can increase Eirika’s Anima magic level and give her an Elfire spell. But, since she doesn’t have a spell casting animation, the game won’t show a battle animation when she attacks or gets attacked.
The only exception I’ve found so far is Myrrh’s Dragonstone. The Dragonstone is special because Myrrh is the only playable character that can wield it. There is probably another variable that determines whether the character can use Dragonstones and with more reverse-engineering we could find it. I won’t dive into it just because you get Myrrh so late into the game and I don’t have any savefiles that far.
But what about profit? I was just kidding. Mostly. You could give a character a bunch of expensive items and sell them back to the store… But since you can give any character any item you want, there really isn’t a use for gold anymore.
Messing around with the memory values is pretty neat. This is actually how GameSharks and ActionReplays work. This can also be applied to any kind of game, regardless of platform. Of course, you’d have to find different tools to do the job, but the concepts are the same. Reading memory is also how a lot of bots for PC games work. From a runtime perspective, reverse-engineering the game and reading data from memory is a lot faster than trying to process what’s on the screen.
Of course, all the changes made here are all temporary. We’ve only been changing variables in RAM and hoping that somewhere down the line the game will save those changes somewhere. We also haven’t changed the fact that we have to manually create these changes. What we really want is to be able to take our ROM, run it on a standard Gameboy Advance, and have all our changes appear. As the name suggests, it doesn’t become a “ROM hack” until you change it permanently in the ROM itself.
We’ll cover that in Part 2!
P.S. If you don’t want to brute force the item values or the other stat addresses, here is a link I found that contains all that information. After trying out some of the values in there, I found that the Dragonstone item seems to be linked to a unit’s class. If you change a unit to be a Manakete or Draco-Zombie class, it will be able to use the Dragonstone.