Skip to content

The Edge of the Cyber World See the latest

Apps

Pokémon Red Emulator: 13 Steps, 55 Min Save Check [2026]

A Pokémon Red emulator boots in five minutes. Trusting it with your progress takes longer, and that gap is where players lose dozens of hours. This tutorial installs mGBA 0.10.5, the latest numbered release on the project site, then walks through a 13-step, 55-minute save check that proves your progress survives a restart, a crash and a bad day.

The test goes beyond pressing Save once and hoping. You will confirm the battery file exists on disk, reopen the game cold, run a separate save-state test, validate the save with a checksum script, and set up rotating backups. If you already keep a loose backup habit, our guide to backing up Pokémon emulator saves covers the general idea. This piece goes deeper on one game, the original Red cartridge image, and on the exact bytes that make a save valid.

One legal note before anything else. mGBA is free, open-source software under the Mozilla Public License 2.0, and its own footer says the project is not affiliated with Nintendo. The emulator is legal to download. The game is a different matter, so this guide assumes you dump your own cartridge and links to no ROM downloads of any kind.

Why a Pokémon Red emulator needs a save check, not just a launch

Pokémon Red is a 1990s Game Boy game, and the series marked its 30th anniversary earlier this year. The cartridge keeps your progress in battery-backed memory. An emulator imitates that memory by writing a file next to your game or in a folder you pick. Everything about save safety comes down to one question: where is that file, and is it the one the game reads when you press Continue?

Two separate systems confuse newcomers. The battery save is the progress the game itself writes when you pick Save from the Start menu. A save state is a snapshot the emulator takes of the whole machine, including memory, CPU registers and the screen. The mGBA project and the RomM documentation on saves and states both treat them as different things, and that difference matters. A state belongs to one emulator and one version, while a battery save is a plain file you can move to another emulator.

Most lost-save stories trace back to one of four causes. A player relied on save states only and later changed emulators. A player moved the ROM folder and the emulator started a fresh, empty save beside the new location. A player closed the window mid-write. Or a player saved over a good file with a bad one and kept no backup. Each cause has a test in this tutorial, and each test takes minutes, not hours.

The 55-minute budget is deliberate. About 23 minutes go to install and setup, 18 to the tests that prove the save works, and 14 to automation. You will not play the game during this time beyond the opening minutes. You will, however, finish with a tool that checks every future session for you.

What “save check” means in this guide

We define a passing save check as five facts, all true at once. The battery file exists in the folder you chose. Its modification time changes when you save in game. The game offers Continue after a full emulator restart and shows the right trainer. The file passes a checksum validation. And at least one dated backup of that file sits in a different folder. If any of the five fails, you have found a problem while it is still cheap to fix.

Prerequisites: versions and files you need

Everything here runs on a normal desktop. mGBA ships builds for several desktop platforms, and the official release notes warn that version 0.10.5 may be the last release to support Windows 7 through 8.1 and macOS 10.9 through 10.12. Pick Windows 10 or newer, a current macOS, or a Linux distribution from the last few years and you stay clear of that cutoff. Our own general mGBA setup for Pokémon games covers the GBA titles, and this guide stays on the original Game Boy.

Item Requirement Why it matters
mGBA 0.10.5 (latest numbered stable on mgba.io) The official site calls it a bugfix release. Development builds labeled 0.11 exist but are not stable releases.
Operating system Windows 10 or 11, current macOS, or recent Linux Release notes say 0.10.5 may be the last to support Windows 7 to 8.1 and macOS 10.9 to 10.12.
Python 3.9 or newer Runs the three helper scripts. No third-party packages needed.
Game image A .gb dump of your own Pokémon Red cartridge Legal source. The header check in step 1 confirms the dump is sane.
Disk space Under 1 MB for saves and states The battery save is 32 KB, so backups cost almost nothing.
Optional A Game Boy cartridge reader Only needed if you dump the cartridge yourself.

Create one working folder before you start. Everything below assumes a layout like the one in the next code block. Windows readers can put it under their user folder, and macOS or Linux readers can use ~/Games/GameBoy. Keeping ROMs, saves, states and backups in four sibling folders makes later mistakes obvious, because a stray file in the wrong place is easy to spot.

GameBoy/
  roms/       Pokemon Red.gb
  saves/      (battery .sav files land here)
  states/     (save states land here)
  backups/    (rotating copies, never touched by the emulator)
  tools/      romcheck.py  redsave.py  make_test_save.py

The current-state note: as of November 2, 2026, we found no newer numbered stable mGBA than 0.10.5, and no official Pokémon Red PC edition. Third-party packagers sometimes publish builds with suffixes like 0.10.5-5. Those are repackaged builds, not upstream releases, so download from the official site and ignore the suffix noise.

Which Pokémon Red emulator should you pick?

mGBA is the pick for this tutorial because it is free, actively maintained, and accurate on Game Boy and Game Boy Color titles as well as the Game Boy Advance library it is named for. Retro Replay’s mGBA profile describes the same scope: an open-source emulator for Game Boy, Game Boy Color and Game Boy Advance, with an emphasis on accuracy and a clean desktop interface. Pokémon Red is a Game Boy title, so it sits squarely inside that support.

Alternatives exist, and the right choice depends on your habits. Windows users who like a debugger and memory viewer often prefer BGB, which we cover in our BGB setup for Pokémon Red, Blue and Yellow. If you want one front end for dozens of systems, RetroArch with a Game Boy core works, though it names its battery file differently. For a head-to-head on accuracy, see our mGBA vs VBA-M vs SkyEmu comparison.

Option Battery save file Save states Best for
mGBA .sav next to the game or in a folder you pick Numbered slots plus state files Accuracy, free, one app for Game Boy and GBA
BGB .sav beside the ROM Yes, emulator-specific Windows users who want debugging tools
RetroArch plus a Game Boy core .srm in its saves folder Yes, per core One launcher for many systems
Browser-based player Kept in browser storage, not a file you control Usually one slot Quick tries, never long playthroughs
Flash cartridge on real hardware .sav copied from the SD card None Playing on an original handheld

Note the RetroArch row. It stores battery data with an .srm extension, and the 2Bluebox guide to RetroArch save paths explains where those files and its states land. The data inside is the same battery memory, so you can usually rename a .srm to .sav and load it elsewhere. Do that on a copy, never on your only file.

Browser players deserve a warning. They are fine for a ten-minute nostalgia hit. They are a poor home for a playthrough, because clearing site data or switching browsers wipes the save, and you cannot back up what you cannot see. Treat any option without a visible file as disposable.

The 13-step, 55-minute plan at a glance

The plan splits into three parts. Part one installs and configures the emulator in steps 1 to 6. Part two proves the save works in steps 7 to 10. Part three automates the checks in steps 11 to 13. The time column is a budget, not a stopwatch, and a first run on a clean machine tends to land close to it.

Step Task Minutes Pass signal
1 Check the ROM header 5 romcheck.py prints PASS
2 Install mGBA 0.10.5 4 The emulator window opens
3 Build the folder layout 3 Four sibling folders exist
4 Point mGBA at saves and states 4 Settings show your paths
5 Load the game and set the Game Boy model 4 Title screen appears
6 Map controls and hotkeys 3 Menu navigates cleanly
7 Start a new game and save in game 5 Game says it saved
8 Verify the .sav on disk 4 File exists, timestamp moved
9 Cold-restart test 4 Continue shows your trainer
10 Save state test, kept separate 5 State loads, battery save unchanged
11 Run the checksum validator 6 redsave.py prints PASS
12 Automate rotating backups 5 Dated copy appears in backups
13 Run a failure drill and restore 3 Corrupt file caught, backup restored

The minutes add up to 55. If you are on step 9 at the half-hour mark, you are on pace. If you are still wrestling with paths at minute 20, jump to the troubleshooting section, because path confusion is the most common time sink.

Part 1: Install and configure the emulator (steps 1 to 6)

Step 1: Check the ROM header (5 minutes)

A bad dump causes strange problems later, and those problems look like save bugs. Check the file first. The Game Boy header at the start of the image records the title, the cartridge type, the save-memory size and a header checksum. Pokémon Red uses a cartridge type that includes battery-backed RAM, and a good dump reports a 32 KB save size.

#!/usr/bin/env python3
"""Sanity-check the header of a Game Boy ROM dump of Pokemon Red or Blue."""
import sys
from pathlib import Path

rom = Path(sys.argv[1]).read_bytes()
title = rom[0x134:0x144].split(b"x00")[0].decode("ascii", "replace")
cart, ram = rom[0x147], rom[0x149]
x = 0
for b in rom[0x134:0x14D]:
    x = (x - b - 1) & 0xFF
print(f"title       : {title}")
print(f"cart type   : 0x{cart:02X} (0x13 = MBC3 + RAM + battery)")
print(f"save RAM    : 0x{ram:02X} (0x03 = 32 KB)")
print(f"header sum  : stored 0x{rom[0x14D]:02X}, computed 0x{x:02X}")
print("RESULT      :", "PASS" if cart == 0x13 and ram == 0x03 and x == rom[0x14D] else "CHECK THIS DUMP")

Save it as tools/romcheck.py and run it against your dump. A healthy file prints the title, then the cartridge and RAM codes, then PASS. If the title prints as something else, you have the wrong game. If the header sum does not match, the dump is damaged and you should dump the cartridge again before going further.

python tools/romcheck.py "roms/Pokemon Red.gb"

title       : POKEMON RED
cart type   : 0x13 (0x13 = MBC3 + RAM + battery)
save RAM    : 0x03 (0x03 = 32 KB)
header sum  : stored 0xB8, computed 0xB8
RESULT      : PASS

That sample output came from a synthetic header built for this article, so your stored checksum byte will differ. The only thing that matters is that the stored and computed values match and the last line says PASS.

Step 2: Install mGBA 0.10.5 (4 minutes)

Download the current build from the official mGBA site and unpack it. Windows users get a zip they can unpack anywhere. There is no installer to fight with. Put the folder somewhere stable, such as C:ToolsmGBA, because moving it later can strand a portable configuration file.

Skip nightly builds and third-party AppImage or repackaged versions for this exercise. Reportedly, development builds labeled 0.11 are circulating, but they are not stable releases, and an unstable build is the wrong place to learn whether your saves are safe. The official release notes for 0.10.5 describe it as a bugfix release with several important fixes, which is exactly the profile you want.

Launch the program once and close it. This first run creates the configuration file, which you will need in step 4. If Windows SmartScreen warns about an unrecognized app, that is normal for open-source builds. Verify that you downloaded from the official site and continue.

Step 3: Build the folder layout (3 minutes)

Create the four sibling folders from the earlier tree. On Windows, the commands below do it in one pass, and the Unix version works on macOS and Linux. Keep the names short and free of unusual characters, because some older tools stumble on accents and long paths.

# Windows (PowerShell)
$Root = "$HOMEGamesGameBoy"
"roms","saves","states","backups","tools" | ForEach-Object { New-Item -ItemType Directory -Force "$Root$_" }

# macOS or Linux
mkdir -p ~/Games/GameBoy/{roms,saves,states,backups,tools}

Copy your ROM into roms and the three scripts into tools as you reach them. The backups folder is special. The emulator never writes there, so a bug in your emulator configuration cannot touch your safety copies.

Step 4: Point mGBA at saves and states (4 minutes)

By default mGBA can write battery files beside the ROM. That works until you move the ROM. Set explicit folders instead. Open the settings dialog from the Tools menu and find the paths tab (the label reads something like Paths and Logs, and exact wording can shift between builds). Set the save games folder to your saves directory and the save states folder to states.

Apply the change, then close and reopen the emulator. Settings that look applied in the dialog but do not persist are a known source of confusion, and one open mGBA issue from October 2026 reports that key-binding changes take effect immediately instead of waiting for OK. Reopening the app and rechecking the dialog costs ten seconds and settles any doubt.

Advanced users can verify the same thing in the configuration file. The Qt front end stores keys named savegamePath and savestatePath, so a quick text search of config.ini confirms the values. You can even override them per launch with the -C option, which becomes useful in the launcher script later.

Step 5: Load the game and set the Game Boy model (4 minutes)

Use File, then Load ROM, and pick your .gb image. Pokémon Red should reach its title screen within a second or two. Next, open the Game Boy section of the settings. Leaving the model on autodetect is the safe default, since the emulator picks hardware based on the cartridge header. Pokémon Red also carries Super Game Boy support, so you may see a border if you enable it, and that is cosmetic only.

Pick a model once and stay with it. Switching hardware modes between sessions changes nothing about the battery file, but it does change how save states behave, because a state captures the hardware model along with everything else. Consistency here prevents a whole class of states that refuse to load. If you want a one-click launch from the desktop with these paths baked in, our Pokémon emulator launcher script shows the pattern.

Step 6: Map controls and hotkeys (3 minutes)

Open the keyboard settings and confirm the defaults work for you. A and B should sit under your right hand, Start and Select within reach, and the directional keys on the arrow cluster. Gamepad users can bind a controller in the same dialog. Test by walking the title menu: press Start, move through the options and back out again.

Write down the hotkeys for loading and saving a state, because step 10 depends on them. The defaults use the function keys, with a modifier for saving and a plain press for loading. Check the shortcut list in the settings rather than trusting memory, since you want the real bindings for your build. Also bind or note the fast-forward key. Fast-forward is great for grinding, but it adds risk if you also use it while saving, so avoid it during the tests.

Part 2: Prove the save works (steps 7 to 10)

Step 7: Start a new game and save in game (5 minutes)

From the title menu choose New Game, then play through Professor Oak’s opening and the naming screens. Name your trainer something short and recognizable, because you will look for that name after the restart. A three-letter name makes a good test marker. Walk out of your bedroom so the game state is clearly different from the starting point.

Now open the Start menu and pick Save. The game asks for confirmation. Say yes. On a fresh game it saves directly. If a save already exists, the game asks whether it is okay to overwrite, and you should read that prompt carefully, because it is the one place where you can overwrite a good file with a worse one. When the game confirms the save, wait a few seconds before touching anything else.

Do not rely on the emulator window as proof. A message on screen shows the game wrote to its simulated memory. Whether the emulator flushed that memory to a file is a separate fact, and step 8 checks it.

Step 8: Verify the .sav on disk (4 minutes)

Open your saves folder in a file manager. You should see a file named after the ROM with a .sav extension. Note its modification time. Go back to the game, walk a few steps, save again, and recheck. The time should move forward. If it never moves, the emulator is writing somewhere else, or the game never completed the save.

Mind the size too. A suspiciously small battery save signals a truncated write, and a file filled with a single repeated byte signals a game that has never saved. Our validator in step 11 checks both automatically, but a quick look now builds the right instincts.

If you are on Windows and the extension is hidden, turn on file extensions in the file manager options. A file listed as Pokemon Red with no extension could be the ROM, the save or a shortcut, and guessing wrong is how people delete the wrong thing.

Step 9: Cold-restart test (4 minutes)

Close mGBA with the normal quit command, not by killing the process. Wait a moment, then relaunch it and load the game. At the title menu you should see Continue as an option. Choose it, and confirm the screen shows your marker name and the badge and time summary. That is the first real proof that the file on disk is the file the game reads.

For a harder test, restart your computer. It is a cheap way to catch the case where a file only existed in a write cache. Then run the Continue check again. If the game shows New Game and Option but no Continue, the emulator did not find a save where it expected one. Go back to step 4 and compare the folder in the settings against the folder you inspected in step 8.

A related trap shows up in other Pokémon titles, where in-game clock or battery behavior breaks saves in different ways. Our Pokémon Emerald clock and save fix covers that GBA-specific case. Red has no real-time clock, so it is simpler, but the cold-restart habit transfers.

Step 10: Save state test, kept separate (5 minutes)

Now test the second system. Walk to a new spot, then use your save-state hotkey to store a snapshot in slot 1. Do not use the in-game Save this time. Close the emulator, reopen it, load the game, and trigger the state load hotkey. You should land exactly where you saved the state, even mid-step, because a state captures everything.

The key observation is what happens to the battery file. Check the modification time on your .sav. It should not have changed, because the state test never touched the in-game save. This confirms the two systems are independent, and it tells you something practical: if you load an old state after saving in game, the game memory goes back in time, and the next in-game save writes that older world to the battery file. That is how progress vanishes. If you plan to edit or inspect the result afterward, our PKHeX save editor guide shows how to open a save safely, though always on a copy.

Treat states as a convenience for experiments, such as testing a risky catch, and never as your record of progress. States are tied to the emulator that made them, so a state from one version or program may not load in another. Battery saves travel better.

Part 3: Automate the checks (steps 11 to 13)

Step 11: Run the checksum validator (6 minutes)

Eyeballing a file only goes so far. Pokémon Red guards its main save data with a one-byte checksum, and the game refuses to load data that fails it, showing a message that the file data is destroyed. The script below recomputes that checksum and compares it with the stored byte. It also decodes the trainer name, money, badge count and play time, so you can confirm the save contains what you expect.

#!/usr/bin/env python3
"""Check and back up a Pokemon Red/Blue battery save written by mGBA."""
import argparse
import hashlib
import shutil
import sys
import time
from pathlib import Path

SAVE_SIZE = 0x8000
SUM_START, SUM_END = 0x2598, 0x3523   # checksum byte sits at SUM_END
NAME_AT, MONEY_AT, BADGES_AT, TIME_AT = 0x2598, 0x25F3, 0x2602, 0x2CED

CHARS = {0x7F: " "}
CHARS.update({0x80 + i: chr(65 + i) for i in range(26)})
CHARS.update({0xA0 + i: chr(97 + i) for i in range(26)})
CHARS.update({0xF6 + i: str(i) for i in range(10)})


def decode_name(raw):
    out = ""
    for b in raw:
        if b == 0x50:
            break
        out += CHARS.get(b, "?")
    return out


def checksum(data):
    return (~sum(data[SUM_START:SUM_END])) & 0xFF


def inspect(path):
    """Return (ok, report_lines) for one .sav file."""
    data = Path(path).read_bytes()
    lines = [f"file      : {path}",
             f"size      : {len(data)} bytes",
             f"sha256    : {hashlib.sha256(data).hexdigest()[:16]}",
             f"modified  : {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(Path(path).stat().st_mtime))}"]
    if len(data) != SAVE_SIZE:
        return False, lines + [f"RESULT    : FAIL, expected {SAVE_SIZE} bytes"]
    if len(set(data)) == 1:
        return False, lines + ["RESULT    : FAIL, blank file (the game never saved here)"]
    want, have = data[SUM_END], checksum(data)
    name = decode_name(data[NAME_AT:NAME_AT + 11])
    money = int(data[MONEY_AT:MONEY_AT + 3].hex())
    badges = bin(data[BADGES_AT]).count("1")
    hh, mm, ss = data[TIME_AT], data[TIME_AT + 2], data[TIME_AT + 3]
    lines += [f"trainer   : {name}",
              f"money     : {money}",
              f"badges    : {badges}",
              f"play time : {hh}:{mm:02d}:{ss:02d}",
              f"checksum  : stored 0x{want:02X}, computed 0x{have:02X}"]
    ok = want == have
    return ok, lines + [f"RESULT    : {'PASS' if ok else 'FAIL, checksum mismatch'}"]


def backup(sav, dest, keep):
    ok, lines = inspect(sav)
    print("n".join(lines))
    if not ok:
        print("Refusing to back up a save that failed the check.")
        return 1
    dest = Path(dest)
    dest.mkdir(parents=True, exist_ok=True)
    stamp = time.strftime("%Y%m%d-%H%M%S")
    target = dest / f"{Path(sav).stem}-{stamp}.sav"
    shutil.copy2(sav, target)
    print(f"backup    : {target}")
    old = sorted(dest.glob(f"{Path(sav).stem}-*.sav"))
    for stale in old[:-keep]:
        stale.unlink()
        print(f"pruned    : {stale.name}")
    return 0


def main():
    p = argparse.ArgumentParser(description=__doc__)
    sub = p.add_subparsers(dest="cmd", required=True)
    c = sub.add_parser("check")
    c.add_argument("sav")
    b = sub.add_parser("backup")
    b.add_argument("sav")
    b.add_argument("--dest", default="backups")
    b.add_argument("--keep", type=int, default=10)
    a = p.parse_args()
    if a.cmd == "check":
        ok, lines = inspect(a.sav)
        print("n".join(lines))
        return 0 if ok else 1
    return backup(a.sav, a.dest, a.keep)


if __name__ == "__main__":
    sys.exit(main())

The checksum covers the main data block, adds up the bytes, and stores the complement of the low byte. If you flip any byte in that block, the computed value changes and the check fails. The script supports this layout for Red and Blue. Save it as tools/redsave.py and run it on your real save.

python tools/redsave.py check saves/"Pokemon Red.sav"

You can test the validator before trusting it with your file. The helper below writes a synthetic save with a valid checksum, and a flag that corrupts one byte, so you can watch both outcomes. The sample outputs in this article come from exactly these scripts.

#!/usr/bin/env python3
"""Write a synthetic Red/Blue save so you can test redsave.py safely."""
import sys
from redsave import SAVE_SIZE, NAME_AT, MONEY_AT, BADGES_AT, TIME_AT, SUM_END, checksum

out = sys.argv[1] if len(sys.argv) > 1 else "saves/test-red.sav"
data = bytearray(SAVE_SIZE)
data[NAME_AT:NAME_AT + 4] = bytes([0x80 + 17, 0x80 + 4, 0x80 + 3, 0x50])          # R E D end
data[MONEY_AT:MONEY_AT + 3] = bytes([0x00, 0x30, 0x00])                            # 3000 in BCD
data[BADGES_AT] = 0b00000011
data[TIME_AT], data[TIME_AT + 2], data[TIME_AT + 3] = 1, 12, 5
data[SUM_END] = checksum(data)
if len(sys.argv) > 2 and sys.argv[2] == "--corrupt":
    data[0x2600] ^= 0xFF
open(out, "wb").write(data)
print("wrote", out, len(data), "bytes")
python tools/make_test_save.py saves/test-red.sav
python tools/redsave.py check saves/test-red.sav

file      : saves/test-red.sav
size      : 32768 bytes
sha256    : a86c270676945fe9
modified  : 2026-11-02 18:11:41
trainer   : RED
money     : 3000
badges    : 2
play time : 1:12:05
checksum  : stored 0xD2, computed 0xD2
RESULT    : PASS

Run it on your real file and compare. Your trainer name should match what you typed, the play time should match the in-game clock roughly, and the result should say PASS. A mismatch between the screen and the script is the signal to stop and investigate before you play further.

Step 12: Automate rotating backups (5 minutes)

The same script includes a backup command. It validates the save first, then copies it into the backups folder with a timestamp, and prunes old copies beyond the number you choose to keep. Validating before copying matters. A rotation that blindly copies a corrupt file will, after enough sessions, replace every good backup with a bad one.

python tools/redsave.py backup saves/"Pokemon Red.sav" --dest backups --keep 10

(... report lines ...)
RESULT    : PASS
backup    : backups/Pokemon Red-20261102-181142.sav

Wire this into a launcher so it runs after every session without you thinking about it. The PowerShell wrapper below checks the existing save before launch, waits while mGBA runs, then backs up after you quit. For a deeper take on this pattern across many emulators, see our Ludusavi emulator save backup tutorial, which handles whole libraries rather than one game.

$Root = "$HOMEGamesGameBoy"
$Mgba = "C:ToolsmGBAmGBA.exe"
$Rom  = "$RootromsPokemon Red.gb"
$Sav  = "$RootsavesPokemon Red.sav"
$Tool = "$Roottoolsredsave.py"

if (Test-Path $Sav) {
    python $Tool check $Sav
    if ($LASTEXITCODE -ne 0) { Write-Warning "Save failed the check. Restore a backup first."; exit 1 }
}
Start-Process -FilePath $Mgba -ArgumentList "`"$Rom`"" -Wait
python $Tool backup $Sav --dest "$Rootbackups" --keep 10

On macOS or Linux, the same idea fits in four lines of shell. Run the check, launch the emulator, wait for it to exit, then run the backup. The script returns a nonzero exit code on failure, so chaining the commands with the shell’s and-operator stops at the first problem.

Step 13: Run a failure drill and restore (3 minutes)

A backup you have never restored is a hope, not a backup. Copy your save to a scratch name, flip a byte with the test helper or a hex editor, and run the check. It should print FAIL with a checksum mismatch and exit with code 1. Then copy a dated backup over your working save and run the check again.

python tools/make_test_save.py saves/bad.sav --corrupt
python tools/redsave.py check saves/bad.sav

trainer   : RED
checksum  : stored 0xD2, computed 0xD3
RESULT    : FAIL, checksum mismatch

python tools/redsave.py backup saves/bad.sav
Refusing to back up a save that failed the check.

Finish by loading the restored save in the emulator and choosing Continue. When that works, you have proven the whole loop: write, verify, back up, break, restore. That loop is the real deliverable of the 55 minutes.

The complete working project in one place

Here is the final state of the project, so you can compare it with your own folder. Three scripts live in tools, one launcher sits wherever you keep shortcuts, and the emulator points at the sibling saves and states folders. Nothing else is required.

File or folder Purpose Written by
roms/Pokemon Red.gb Your own cartridge dump You, with a cartridge reader
saves/Pokemon Red.sav Battery save, 32 KB mGBA, when the game saves
states/ Snapshot files from the save-state hotkeys mGBA
backups/ Timestamped, validated copies of the save redsave.py backup
tools/romcheck.py Header sanity check for the dump You
tools/redsave.py Checksum validator plus rotating backup You
tools/make_test_save.py Synthetic save for drills You
play-red.ps1 Check, launch, wait, back up You

A normal session now looks like this. Double-click the launcher, which checks the save and starts the emulator. Play and use the in-game Save before you quit. Close mGBA with its quit command. The wrapper validates the final save and drops a dated copy into backups. If something looks wrong at any point, the previous ten copies are one file copy away.

One habit completes the project: save in game before you quit, every time, and treat the state hotkeys as scratch space. Players who follow that rule rarely need the backups. The ones who skip it are the reason the backups exist.

What good and bad output looks like

Knowing the failure shapes saves time. The table below maps what the validator prints to what happened. All three outputs below come from the synthetic test saves described earlier, which let us trigger each failure on purpose.

Validator output What it means Next move
RESULT : PASS Size, checksum and fields are consistent Back up and keep playing
FAIL, checksum mismatch A byte in the main data changed after the game saved Restore the newest passing backup
FAIL, expected 32768 bytes Truncated, padded or the wrong kind of file Check you picked the .sav, not a state
FAIL, blank file The game never saved to this file Check the save path and save in game again
python tools/redsave.py check saves/short.sav
file      : saves/short.sav
size      : 100 bytes
RESULT    : FAIL, expected 32768 bytes

python tools/redsave.py check saves/blank.sav
file      : saves/blank.sav
size      : 32768 bytes
RESULT    : FAIL, blank file (the game never saved here)

The blank case surprises people. A file of the right size filled with one repeated value looks fine in a file manager. The emulator creates such a file at first launch, which is why a save that exists on disk is not proof of anything until the game has written to it.

Common pitfalls that cost players their saves

These six mistakes account for most save-loss stories on forums and in our reader mail. Each one has a one-line prevention.

Pitfall What happens Prevention
Relying on save states only A state belongs to one emulator version, so an update or switch strands it Always use the in-game Save, then treat states as scratch
Loading an old state after an in-game save Memory rolls back, and the next in-game save writes the older world over the good one Back up the .sav before any state experiment
Killing the emulator mid-save The write is incomplete, leaving a short or inconsistent file Quit with the menu command and wait a few seconds after saving
Leaving the save path on the default Moving the ROM folder spawns a new empty save beside it Set explicit folders in step 4 and recheck after any move
Backing up blindly A rotation copies a corrupt file over every good backup Validate first, as redsave.py backup does
Editing the only copy A save editor or hex change that goes wrong has no undo Edit a copy and compare checksums before swapping it in

The sixth pitfall matters most for challenge runs. Players who follow strict self-imposed rules, like the ones in our Nuzlocke on an emulator setup, depend on a clean, honest save history. A rotating backup with timestamps doubles as an audit trail when you wonder what happened three hours ago.

A seventh trap hides in cloud sync tools. A sync folder that holds both the live save and a stale copy can overwrite the new file with the old one when two machines disagree. If you sync, sync the backups folder only, and keep the live saves folder local.

Troubleshooting: ten problems and their fixes

  1. No Continue option after restart. The emulator is reading a different folder than the one you inspected. Compare the save path in settings against the folder holding your .sav, fix the setting, and relaunch.
  2. The .sav timestamp never changes. Either the game did not complete the save or the emulator writes elsewhere. Save again in game, wait a few seconds, then search the ROM folder and the configuration directory for recently modified files.
  3. The game shows that the file data is destroyed. The checksum failed. Run redsave.py check on the file and on your newest backup. Restore the newest passing copy and note what happened before the corruption.
  4. The validator says the file size is not what it expected. You pointed it at the wrong file, often a state or a file from another emulator with extra header data. Confirm the extension and size, and try the file in the folder where mGBA writes battery saves.
  5. The validator reports a blank file. The emulator created an empty save at launch and the game has not written to it. Save inside the game and wait before running the check again.
  6. A save state will not load. The state came from a different mGBA version or hardware model. Load the game with the original settings, or fall back to the battery save. This is why states never replace saves.
  7. Settings do not persist. Close the emulator from its menu so it writes the configuration, then reopen it. If the install folder is write-protected, move the program to a user-writable location.
  8. The save works but progress looks older than expected. You may have loaded an old state and saved over newer progress. Check your backups for the most recent file with the right play time and restore it.
  9. The backup script prunes too much. The --keep value is a count of files. Raise it, and confirm the backup folder name matches the game stem, since pruning only touches matching files.
  10. The ROM header check fails. Dump the cartridge again, clean the contacts, and compare. A repeated failure on a good dump means the file belongs to a different revision or a patched image, so make sure it is the game you expect.

If none of those match, capture three facts before asking for help: your exact mGBA version, the full path of the save folder from settings, and the output of the validator. With those, most problems resolve in one message.

Advanced tips for longer playthroughs

Once the basics work, a few upgrades pay off over a multi-week playthrough. First, back up at milestones as well as at quit. Before a gym leader, before the Safari Zone and before any long cave, copy the save by hand under a descriptive name such as before-brock.sav. Descriptive names beat timestamps when you need to find a specific moment.

Second, schedule a hash log. Appending the short SHA-256 value from each check to a text file gives you a cheap history. If two backups from different days share a hash, nothing changed. If a hash changes without play time moving, something wrote to the file outside the game.

Third, use version control for your tools folder. A three-script project is small enough that a plain Git repository tracks it fine, and it keeps you honest about any changes to the checksum logic. Keep the save files out of the repository unless you enjoy large, noisy commits.

Fourth, keep a second backup location. A copy on the same disk survives a corrupt save but not a dead drive. Mirror the backups folder to an external drive or a cloud folder on a schedule. As noted earlier, mirror only the backups, never the live save folder.

Fifth, test restores on a calendar. Pick the first of each month and run the failure drill from step 13 on a scratch copy. Thirty seconds of practice keeps the procedure fresh and surfaces silent breakage, such as a moved folder or an expired scheduled task, before you need the backup.

Finally, consider the same discipline for other versions. The checksum approach used here fits Red and Blue. Pokémon Yellow and the later Game Boy Color titles use different layouts, so extend the script only after reading a reliable memory map for that game, and verify your changes against known-good saves.

Official routes and the current state in November 2026

The emulator path is not the only way to play. Nintendo’s own pages confirm that Nintendo Switch Online and Switch 2 are active products as of late October 2026, and the company runs a Game Boy Classics library inside the subscription. Based on the October 2026 Nintendo update pages we checked, the newly announced Game Boy additions did not include Pokémon Red, so treat Red’s availability there as unconfirmed. Nintendo’s results also do not document any compatibility between Switch Online save data and the mGBA .sav files discussed here.

The older digital route has also closed. Nintendo’s UK site states that, as of 27 March 2023, buying from the eShop for Wii U and the Nintendo 3DS family is no longer possible. New purchases of the old Virtual Console release are off the table on that hardware.

Pokémon’s own news feed describes a different 2026 development. FireRed Version and LeafGreen Version, the Game Boy Advance remakes, connect with Pokémon HOME according to a pokemon.com post, and Nintendo lists Pokémon FireRed Version on its platform. Those are remakes, not Red, and their saves do not follow the Red layout this tutorial validates. On the merchandise side, Pokémon Center restocked the Pokémon Red and Blue Game Boy Jukebox on October 9, 2026, which is a collectible and not software.

The bottom line for November 2026: no official PC release of Pokémon Red exists in the sources we checked, no new stable mGBA has appeared since 0.10.5, and your own cartridge dump remains the clean path for emulator play. For more setup guides in this vein, browse our gaming section.

FAQ: Pokémon Red emulator saves

What is the best pokemon red emulator for PC?

For most players it is mGBA 0.10.5. It is free, open source, actively maintained and accurate on Game Boy titles. BGB is a good alternative on Windows if you want debugging tools, and RetroArch suits people who want one front end for many systems.

Where does mGBA store my Pokémon Red save?

Wherever you tell it to. By default it can write the battery file next to the ROM, which is why this guide sets explicit save and state folders in step 4. Confirm the location by checking the modification time on the .sav after saving in game.

What is the difference between a .sav file and a save state?

A .sav is the game’s own battery memory, written when you pick Save in the Start menu. A save state is the emulator’s snapshot of the whole machine. The save travels between emulators, while a state usually does not. Use the .sav as your record and states as scratch space.

Can I move my Pokémon Red save to another emulator?

Usually yes. Copy the .sav to the new emulator’s save folder and name it after the ROM, or rename a RetroArch .srm to .sav. Always work on a copy, and run the validator on the file before and after the move.

How often should I back up my save?

Automatically after every session, plus a manual named copy before any risky milestone. The script in this tutorial validates and rotates ten copies by default, which is enough for most playthroughs.

Is it legal to use a Pokémon Red emulator?

The emulator itself is legal software. mGBA is open source under the Mozilla Public License 2.0 and is not affiliated with Nintendo. Game images are a copyright matter, so this guide assumes you dump a cartridge you own and links to no downloads. Check the rules in your own country.

Does the checksum script work for Pokémon Yellow or Gold?

No. It targets the Red and Blue layout. Other games store data in different places and may use different checks, so extend the script only after verifying a trustworthy memory map for that title.

Why does my save disappear after I update mGBA?

Usually the update reset the configuration or the program folder moved, so the save path fell back to a default. Reopen the settings, confirm the save and state folders, and your .sav should appear again. This is another reason to keep saves outside the program folder.

Related Coverage

Source: Tech Insider