More than 15 years ago, on my eighth birthday, my parents bought me my first ever video game console and my first ever video game to go with it – a Gameboy Advance, and Pokemon Silver.

This is the story of how I managed to preserve these childhood memories just in time, by modifying just one byte of my save file.

Pokemon is pretty special

Nowadays, video gaming is one of my biggest hobbies, and I can confidently say my interest in it stemmed from this birthday present. Most of my friends at school had a Gameboy Color with one or more Pokemon games and I was so excited to be able to join them. I still remember playing the game for the first time and early on being faced with the difficult choice of which starter to pick, before finally deciding on a Totodile. I even nicknamed it “Stef” (my own nickname), and this would become the only Pokemon I’ve ever nicknamed (preferring to keep the name of a Pokemon as its species).

Pokemon became a huge interest within video gaming for me. Pokemon Sapphire came out a year after getting my Gameboy Advance. I played that non-stop for years, and later Pokemon FireRed to catch up on Generation 1 (which I had never played). I’ve built up a collection of all of the main series Pokemon games (including the ones I was missing from the early generations – tracking down an authentic copy of Pokemon Crystal was quite a challenge!) and I am eagerly awaiting the release of UltraSun and UltraMoon later this year. All this while I was content knowing I could always return to the earlier Pokemon games and have all of my Pokemon from childhood there.

However, this isn’t exactly the case for Generation 1 and Generation 2 Pokemon games (Pokemon Red, Blue, Yellow, Gold, Silver and Crystal, made for the Gameboy and Gameboy Color). These games use SRAM to store their save data, which is a battery-backed RAM chip. When a RAM chip loses power its contents are cleared. In the case of the SRAM inside the Generation 1 and Generation 2 Pokemon games, the save data is lost when the battery runs out.

Backing up my save

Looking at anecdotes from others show that the battery inside Pokemon Silver tends to start running out after 10 or so years. Over the last few years I’d been periodically checking if my Pokemon Silver save was still working (I left my Gameboy and games at my parents house when I moved to a different city, but whenever I was home I would check), and up until a few months ago (the last time I was home) the save was surprisingly still here. It had been more than 15 years since I’d started playing the game, so I knew I didn’t have much time left before my save was lost.

I had been wanting to backup my save to avoid losing it but hardware required was expensive and often difficult to find. About a year ago I discovered a Gameboy enthusiast known as BennVenn who manufactures a Gameboy/Gameboy Color/Gameboy Advance cart reader/writer known as the Joey Joebags, which was up to date, used USB instead of something outdated like serial and was reasonably priced, but it was always out of stock when I checked.

Last week I did a random check on BennVenn’s shop and noticed the Joey Joebags was in stock. I also had family coming to visit that weekend me who could bring me my Gameboy and games, so the timing was perfect. I ordered the Joebags right away, and did a check on my Pokemon Silver save game when my family came to visit a few days later. The save file was still completely fine, so all I had to do was wait for the Joebags to arrive.

The Joebags ended up arriving in just over a week. This was much quicker than I had expected – it was shipped from the USA, and I live in Australia, so I figured it would take a lot longer to arrive. I was glad it was so quick because I had no idea how much longer my save would last! I spent the day at work telling everyone about what this obscure piece of hardware was and how I was going to finally backup my original Pokemon game save, before excitedly heading home to get everything setup.

After installing the drivers (which involved disabling the Windows 10 security feature which prevents unsigned drivers from being installed) I had the Joebags ready to go to backup my save. Just before plugging my game cart into the Joebags, I decided to test it one last time in my Gameboy. I switched on the Gameboy and went through the title screen of Pokemon Silver, and saw that the “Continue” option was still present. I was aware that when the battery ran out it would often lead to no “Continue” option showing, so I was fairly confident all was well at this point. I proceeded to select “Continue” to load the save, and..

“The save file is corrupted!”. My heart sank. I was absolutely shattered. I’d come this close, only to lose my save file in the span of the last few days.

Making the best of it

Looking up causes of Pokemon error messages confirmed that one of the possible reasons for a “The save file is corrupted!” error was that the battery had almost run out, which made sense given it was a game cart over 15 years old.

After pulling myself together, I decided that I may as well dump the game ROM and attempt to backup the save file. I figured that if I’d gone as far as purchasing some niche hardware I may as well use it for something. I plugged my Pokemon Silver cart into the Joebags and used the software to read the cart headers, which were all as I expected.

I then dumped the ROM from the game. As expected, the game dumped perfectly, and was fully playable in an emulator. Despite being somewhat of a consolation prize I was happy to at least have a backup of my first ever video game. I thought I may as well try to backup the save file also, expecting an error, but the software successfully wrote a file from my game cart.

Before I go on I’ll give a quick explanation of what a save file is. You may be familiar with the “.sav” type files an emulator creates when you save a game you playing. These are analogous to what stored is the game cart. The data inside is binary data – ones and zeroes. To make it easier to examine the file, we group the ones and zeroes (the bits) in groups of eight, called “bytes”. The value of a byte is the value of the binary number (base 2) that the eight bits represent, which ranges from 0 to 255 in decimal (base 10).

However, bytes are usually expressed in hexadecimal (base 16) for simplicity and brevity, meaning the range of a byte is 00 to FF. Hexadecimal (“hex”) numbers are often written with a 0x prefix to differentiate them from decimal numbers. For example, the range of a byte would be written as 0x00 to 0xFF. Hex values are also used to refer to the location of data (the address) in a binary file. For example, if 256th byte in a binary file had a value of 100, we could say “the value at the address 0x0100 is 0x64”.

Pokemon Silver has a 32KB SRAM, so the save file is also 32 KBs. The bytes in this file represent all of the information about your save, including your trainer name, Pokemon, game progression and such like (although not all of the bytes are used). The known parts of the save data structure are documented in various places online, with the most reliable documentation I found on Bulbapedia. When talking about the Pokemon Silver save file, it’s safe to assume any hex value with four digits is an address, and any hex value with two digits is data.

Given that my save obviously wasn’t working correctly, I thought that perhaps the Joebags software always wrote out a file of the correct size regardless of whether it could read the SRAM or not, and either wrote all 0x00 or 0xFF or garbage data if the battery was dead or dying. I opened Pokemon Silver in an emulator with the save file I had gotten off my cartridge and noticed that the “Continue” option was present. This made sense because I assume the emulator would have put whatever data was in the correctly named “.sav” file into it’s emulated SRAM. I tried to select the “Continue” option and was presented with the “The save file is corrupted!” error, same as on my Gameboy.

On a whim, I decided to try and open the save file in a Pokemon Generation 2 save editor (everyone has one of those laying around, right?). It gave me a “not a valid Pokemon save file” error message (as expected), but then it presented me an option to “force as a Pokemon save”. I was wondering what it meant by that until I remembered that the Pokemon save file contains a checksum; likely used by the game to verify that the file is not corrupt. A checksum is basically a value derived from related values (in this case, adding up certain values in the save file and taking part of the result), which can then be checked when the save is loaded. The game does the same checksum calculation on the same values in the save and compares the result with the checksum value in the save file. If there is the mismatch, the save file is considered corrupted.

Using the “force as a Pokemon save” option fixed the checksum value in my save file and opened the save in the save editor. I was in disbelief – my trainer name, ID, rival name, Pokemon, pack, Pokedex and PC boxes were all there!

Back in business

There were a few oddities (some glitched items in my pack and some glitched Pokemon in the PC), but for the most part everything was as I’d expected. I was so ridiculously happy – even if though the save wouldn’t load, the bytes with the parts I considered most important (including my first ever Pokemon, the now Feraligatr nicknamed Stef) were still intact. I could still extract those bytes and put them into another save file if I wanted.

Hang on. If the checksums were fixed, doesn’t that mean the game would now load the save?

It was working!

.. but not quite. Notice the graphical oddities? Also, alarmingly, my player couldn’t move, and was facing the wrong way (I saved facing the PC).

That being said, it wasn’t all bad. The next thing I did was try to see if the menu worked, and it did! Everything displayed correctly – my Pokedex, my Pokemon, my pack (including some weird items), my trainer card, and my options.

At this point I’d been tinkering on my save file for about an hour and I was pretty happy with the results. I figured I’d call it a day given I’d managed to preserve the most important parts of the save. I started preparing dinner, but I just wasn’t able to shake the “what if” question. What if I managed to modify the save file and somehow fix the corruption? Like, it was a long shot, but the save file format seemed to be documented, and save file editors exist, so I thought it might be worth an attempt. The save file must contain some information somewhere about the map location of the player, which seemed to be corrupt, so perhaps I could fix that.

I’d come this far, so I figured I may as well see how far I could go.

Debugging my save – finding the location data

Thirty minutes later I was sitting back at my computer ready to start debugging the save. I had a hex editor ready to go to more easily navigate and view the save file and I’d written a simple build script to test my work. It made a copy of my save with the desired name and moved it into a new directory with a copy of the game, fixed the checksums and opened it in an emulator. Making copies of the save every time after I made some changes (with a descriptive name) allowed me to jump quickly back and forth between trying different things.

Unfortunately, initial progress was slow going. I couldn’t find any references to where the player location data was stored in the save file. I guess this makes sense – if you want to edit your save file, you probably want to change your Pokemon levels or add items to your pack, not move your player location around (which is something that is easy enough to do in game). The only references to map data for Pokemon Silver I could find was for map data in the game itself (in the ROM), which was useful for people wanting to make ROM hacks (custom player made Pokemon games) based on the game files. However, I got extremely lucky with an obscure forum post talking about accessing the map data in the ROM. On the “Skeetendo” forums, user “Miksy91” observed:

“The table [at 0x15319] is like this: [Map Bank] [Map Number] [X] [Y] which tell either the blackout map (loaded when losing a battle) or the map where you can fly to. The first four bytes are 0x18 0x07 0x03 0x03 which tell the starting position of the game as well.”

This tiny piece of information had so much potential. I created a new fresh game of Pokemon Silver and saved as soon as I possibly good after the introduction sequence finished. I opened this save in my hex editor and searched for the bytes “0x18 0x07 0x03 0x03”, and they were in exactly two places. One was at 0x2868, and the other a mirrored redundancy section of 0x2856 to 0x2889 (so effectively it was only in one place). I now knew exactly where in the save the player location was stored.

I attempted a quick fix of my original save by copying the bytes for the initial player location (0x18 0x07 0x03 0x03) to the player location part of the save file (starting at 0x2868). I didn’t expect it to work completely, but it was worth a shot. Sure enough, my original save with this modification loaded into the player’s room.. kind of.

While the graphics were totally garbled, and the player sprite was invisible, that was the correct tile set. Also, the correct music was playing, and the menu was still functional. Clearly the game was storing more than just those four bytes to persist the player location data.

Debugging my save – determining what was corrupt

I decided to take a different approach and try to narrow down where the corrupted data in my save was. I found out that the save structure has five important regions which are saved twice in different locations (likely for redundancy). I used my fresh save of Pokemon Silver and proceeded to copy the relevant sections from my original save file into the fresh save file one by one, each time testing the results. Three of the duplicated regions when copied into the new save worked properly, including my Pokedex, Pokemon and pack. This made sense given I could see it all in the save editor already.

The remaining two regions caused issues in the fresh save when copied across. The first, which I dubbed the “player metadata” region, caused my player to not be able to walk. However, it did successfully copy data like my player name and trainer ID. There was a lot of data in this section that wasn’t documented, so I then changed the data I was copying to only the known data, and everything worked. For the small subsections of unknown data, I copied them over one by one until I found the small group of bytes which caused the player to not be able to move: 0x2057 to 0x206A. I never ended up discovering exactly what the data in this region does (it’s situated between the time played and the player palette, for what it’s worth), but I suspect it’s something to do with the direction the player is facing, the tileset, and similar data. I’m not sure why the data here caused my player not to be able to walk, but again I suspect it needs values which align with the rest of the location data in the save for the game to run correctly.

The other region which caused issues was the region which contained the map bank, map tile, x coordinate and y coordinate bytes I’d discovered earlier. This region is 0x2856 to 0x2889, and isn’t documented anywhere I could find. I figured the whole region might be related to player location, so it made sense it caused issues in the fresh save when copied across. I decided to copy the whole region from my fresh save into my original save, along with the small amount of player metadata that seemed to restrict movement.

This was certainly an improvement from my earlier attempt at just copying the four known location bytes. As I had suspected, the game used data from this whole region to record the player location. There continued to be a notable lack of the player, however, the menu still functioned.

Debugging my save – using the game itself

Up to this point I’d been so focused on trying to fix my save file by hand that I’d forgotten that I had the perfect tool for doing so – the game itself. The game knew exactly where in the save file to put everything, and knew exactly the appropriate values to put. I realised that I didn’t have to do everything manually – what if I just made enough change to let me perform in game actions to restore the game to a playable state, and then saved? This would fix the save, or at least, fix it to a reasonable point.

The menu had been functional this whole time, including after injecting various changes into my original save. However, I was never able to use one of the escape moves (fly, dig, teleport, escape rope). Fly and teleport weren’t working because I was indoors, and dig and an escape rope required being in a cave or dungeon. I was indoors because I had injected the initial player location data from my fresh save into my original save, but I realised that I didn’t have to use that exact data now that I knew the relevant locations in the save file to modify. I created another new game, and this time save out on Route 29. I injected all of the relevant data from that save into my original save (small piece of player metadata, and the whole player location section), and loaded the save.

Route 29 loaded with no player sprite as expected. I opened the menu and selected Fly, and it took me to the fly menu! Interestingly though the only available option was New Bark Town. It seemed that somewhere in the data I’d overwritten were the unlocked flight points (and I’d overwritten it with the only unlocked flight point at the beginning of the game, New Bark Town). Nonetheless, I flew to New Bark Town, not knowing what to expect, and..

It worked! The game was playable!

I did some quick tests – talking to NPCs worked, surfing worked, wild battles worked, trainer battles worked. It wasn’t a total fix given all the flight points being lost, but I’d managed to find a way to mostly fix the corruption.

At this point I decided to further refine my goal – I wanted to make the most minimal possible change to my original save file while repairing it. Doing this would preserve the integrity of the save as much as possible (well, as much as possible given it was corrupt). Along the way I was also hoping this would fix the flight points missing issue, and any other small bugs that likely existed. I reduced the amount of the save file I edited bit by bit, testing with each edit, and eventually realised that I only needed to change the player location map bytes to Route 29 (starting at 0x2868). The game loaded into a garbled version of the map, but I was still able to fly away and fix everything, now with all flight points enabled.

I took this one step further when I realised I didn’t need Route 29 specifically, nor any specific x and y coordinates – just any outdoor route. My original save file had 0x19 as its map bank, and 0x06 as its map ID. I looked this up in the ROM documentation and it resolved to the shared Pokemon Center map, which made sense given that was the last place I’d saved with the game working correctly (and also where the save loaded into originally). I found a suitable map in map bank 19 – Route 14, which has an ID of 01.

By modifying just one byte of my save file, changing 0x2869 (map ID) from 0x06 (Pokemon Center) to 0x01 (Route 14), I was able to load into a garbled Route 14, fly away (to Indigo Plateau, as I was in Kanto now), then save in a fixed game.

Debugging my save – bonus round

In the process of determining which parts of my save were corrupt (by copying over sections at a time to a fresh save and noting the results) I discovered that something between 0x2057 and 0x206A in the player metadata section was causing the player to not be able to walk. By comparing values in this section across various fresh (not corrupted) saves and my saves I noticed that 0x2068 was always set 0x0B except in my original save when it was set to 0x09. However, I didn’t end up using this information after I started going down the path of trying to use fly.

Putting this blog post together required recreating some of the save states I got in. While I was doing so I decided to see if changing just that one byte in my original save at 0x2068 from 0x09 to 0x0B did anything. To my surprise, that was enough to allow player movement!

I was able to move around the glitched Pokemon Center (although there were some invisible walls). Attempting to talk to somebody or use the PC didn’t show any speech dialog and prevented further movement. However, warping (either leaving the Pokemon Center or heading upstairs) fixed the game!

It seems that reloading the map was all that was required, which was also what I happened to be doing when flying. I think this is an even better solution to changing the map ID as it preserves even the player location of my original save file.

Closing thoughts

I managed to pull it off – I recovered and repaired my original Pokemon Silver save file. I’m sure there are still some lingering obscure bugs but I’m more than satisfied with how this ended up, given how I initially thought I’d lost it all. My next project will be to finally replace the batteries in my Pokemon games. I’ve been putting it off since I want to replace them all at the same time, and I didn’t want to lose my Pokemon Silver save by removing the battery. Now that I’ve got a backup of it I can proceed!

Later on, I’m planning to inject my repaired save file into a virtual console copy of Pokemon Silver on my 3DS. Nintendo is releasing Pokemon Gold and Pokemon Silver on the virtual console on September 22nd and they will be fully compatible with the Pokemon Bank. This will allow me to “legitimately” transfer my Pokemon into the Pokemon Bank (and then into current generation Pokemon games). Preserving this small part of my childhood was a challenge but I feel it was completely worth it. I’m looking forward to being able to play through future Pokemon games alongside my first ever Pokemon, Stef the Feraligatr.