Pokémon Emerald Emulator Fix: 13 Steps, 50 Min [2026]

Pokémon Emerald is the Game Boy Advance title that fails quietly. The intro plays, the first route loads, and the emulator looks fine. Then three real-world hours later your berries have not grown, the Shoal Cave tide never moves, or the game claims there is no save after you closed the window. All three problems trace back to hardware that the cartridge carries and the emulator has to imitate: a flash save chip and a battery-powered real-time clock.

This guide fixes both on mGBA, the open-source emulator that covers Game Boy, Game Boy Color and Game Boy Advance. As of October 30, 2026, mGBA 0.10.5 is still the newest numbered stable release you can confirm, while 0.11 builds remain development snapshots with no published release date. You will build a clean project folder, verify your own ROM dump, force the right save type and clock support, test the clock inside the game, and finish with a Python script that checks every save sector and keeps rotating backups. If you have never installed the emulator, run through our mGBA setup guide for Pokémon games first, because this tutorial skips the basics and goes straight at the Emerald-specific traps.

Plan on about 50 minutes for the first pass and 10 minutes for every later session. The tutorial has 13 steps, a full set of copy-ready code blocks, four reference tables, a ten-item troubleshooting list, and a finished project you can copy as is. Everything here assumes you play a copy of Emerald that you own and that you dumped from your own cartridge. The article does not link to ROM downloads and will not help you find them.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

What You Need Before You Start

The list is short, but versions matter. mGBA publishes bugfix releases quietly, and a few third-party packages carry version strings that look official and are not. The table below pins down what this tutorial was written against.

ItemRequirementWhy it matters
EmulatormGBA 0.10.5 (stable)Newest numbered stable release confirmed as of October 30, 2026
ScriptingPython 3.9 or newerThe checker uses only the standard library, no pip installs
Operating systemWindows 10 or 11, a current macOS, or a mainstream Linux distromGBA ships Qt builds for all three
Game dumpYour own Emerald cartridge dump, 16 MiB, game code starting BPEThe ROM check in Step 3 rejects anything else
Save typeFlash 128KThe save format Emerald expects when a manual choice is needed
Free timeAbout 50 minutesMost of it goes to the clock test in Step 8
Optional hardwareA GBA cartridge dumperOnly needed if you have not dumped your cartridge yet

Be exact about the emulator channel. The official mGBA site describes 0.10.5 as a bugfix release and says it will be the last release before 0.11 unless a major issue turns up. The same note warns it may also be the last release to support Windows 7 through 8.1 and macOS 10.9 through 10.12. Meanwhile an October 12, 2026 issue on the project tracker lists 0.11.1 as a milestone with no due date, which means it is planned work and not a download. The channels break down like this.

ChannelVersion labelUse it for Emerald?
Official stable0.10.5Yes, this is the build the tutorial uses
Development builds0.11 snapshotsOnly on a throwaway copy of your save
Planned releases0.11.1 milestoneNo, no release date exists
Third-party repackagesLabels such as 0.10.5-5No, a repackaged AppImage is not an upstream release

The legal line is simple. Emulators are legal software. The game file is the part that needs care. Dump the cartridge you own with a dumper, keep the file on your own machine, and do not share it. A cartridge is also worth protecting for its own sake. One market tracker reportedly priced a loose U.S. Emerald cartridge at $219.99 on October 29, which is a single-source figure, but it explains why many players dump once and then retire the original to a shelf. Nintendo does sell some Game Boy Advance games through Game Boy Advance Nintendo Classics for Nintendo Switch Online + Expansion Pack members, yet that service is a separate product and does not give you a save file you can move into mGBA.

Why Pokémon Emerald Breaks on Emulators That Run Other GBA Games Fine

Most GBA games are forgiving. They ship with a battery-backed SRAM chip or a small EEPROM, they ignore the clock, and an emulator that guesses the save type from a few bytes in the ROM gets it right. Emerald is the opposite. It uses a flash chip that has to be erased and rewritten in sector-sized chunks, and it reads a real-time clock that lives on the cartridge board. An emulator that mishandles either one still boots the game, which is why the bug reports usually arrive days later.

The save chip: 128 KiB of flash, two rotating slots

Emerald stores its progress in 128 KiB of flash memory. Current documentation and setup guides treat the save type as Flash 128K, and the troubleshooting pages say to select that type by hand wherever the emulator lets you choose. Setup documentation describes the chip as flash and not battery-backed SRAM, which is an easy mix-up because the cartridge also carries a battery for a different job.

Inside that 128 KiB the game writes 32 sectors of 4,096 bytes each. Two save slots of 14 sectors each alternate, and the game always writes the older slot before bumping a counter stored in every sector footer. Pull the plug mid-write and the other slot still holds the previous save. That design is clever, and it also explains the most important behavior in this tutorial. An emulator that kills the process before it flushes the file to disk can leave a half-written slot, and the game then falls back to the previous slot without telling you. You lose recent progress and see no error.

The clock: a battery that only the cartridge has

The second piece is the real-time clock. Emerald uses it for berry growth, the Shoal Cave tide cycle, the daily Lilycove lottery number and other time-gated events. On a real cartridge a small battery keeps that clock running. When the battery dies, the game shows a message that the internal battery has run dry and the clock-based events stop happening, while the rest of the game stays playable. Players who bought old cartridges know this screen well.

An emulator has to stand in for that battery. mGBA does it by driving the clock from your computer, and the project describes real-time clock support that works without special configuration. A 2026 setup guide citing the libretro documentation says the libretro build of mGBA does the same and keeps clock-dependent events such as berry growth and tides working. The detail to watch is the save file. One documented integration reports that mGBA 0.10.2 can append a 16-byte clock record to the save, which makes the file 131,088 bytes instead of 131,072. Treat that as a reported behavior, not a rule. The checker in this tutorial handles both sizes, and we will come back to the trailer in Step 13 when you move saves between emulators. If you want a feel for how mGBA compares with other cores on accuracy, our mGBA vs VBA-M vs SkyEmu accuracy test covers the timing side.

Put together, the failure modes fall into a handful of patterns, and the rest of the tutorial maps onto them.

Symptom you seeMost likely causeFixed in step
Save vanishes after closing the emulatorWrong save type or unflushed writeSteps 7, 9 and 10
Berries never grow, tide never changesClock support off or wrong in-game timeSteps 7 and 8
Save loads on one machine, not anotherSize mismatch from a clock trailerStep 13
Game starts a new file after a renameThe .sav name no longer matches the ROMSteps 3 and 5
Progress rolls back a few minutesA damaged slot, the game fell back to the other oneSteps 10 and 11

Steps 1 to 3: Folders, a Clean Dump, and a ROM Check

Step 1: Create the project folder. Keep everything in one tree so backups, the emulator and your scripts never wander into different directories. The layout below is the one the finished project uses. On Windows open PowerShell and run the first block. On macOS or Linux use the second.

# Windows (PowerShell)
$Lab = "$env:USERPROFILE\emerald-lab"
New-Item -ItemType Directory -Force "$Lab\roms","$Lab\saves","$Lab\backups","$Lab\tools","$Lab\mgba"
# macOS and Linux
mkdir -p ~/emerald-lab/{roms,saves,backups,tools,mgba}
ls ~/emerald-lab

You should see five empty folders: roms, saves, backups, tools and mgba. If a folder is missing, the later scripts will fail with a path error, so fix it now.

Step 2: Put your own dump in roms and give it a stable name. Copy the dump into the roms folder and rename it to pokemon-emerald.gba. The name matters more than it looks. mGBA derives the save file name from the ROM name, so renaming the ROM later makes the emulator look for a different save and start a blank one. Choose the name once and never touch it again. If you maintain several regional dumps, give each its own descriptive name, such as pokemon-emerald-usa.gba, and keep one save per ROM.

Step 3: Verify the dump with the checker script. A bad dump is the single most common reason for a game that boots, runs for a while and then corrupts its own save. Save the script below as tools/emerald_doctor.py. It has three subcommands. rom checks the header, save validates every save sector, and backup copies a save into a rotating folder. You will use all three before the tutorial ends.

#!/usr/bin/env python3
"""emerald_doctor.py - check a Pokemon Emerald ROM dump and its save file."""
import argparse
import hashlib
import shutil
import struct
import sys
import time
from pathlib import Path

ROM_SIZE = 16 * 1024 * 1024
SAVE_SIZE = 128 * 1024
SAVE_SIZE_RTC = SAVE_SIZE + 16
SECTOR = 4096
SIGNATURE = 0x08012025
SECTION_SIZES = [3884, 3968, 3968, 3968, 3848, 3968, 3968,
                 3968, 3968, 3968, 3968, 3968, 3968, 2000]
REGIONS = {"E": "USA/English", "J": "Japan", "F": "French",
           "D": "German", "I": "Italian", "S": "Spanish"}


def say(level, text):
    print(f"[{level:<4}] {text}")


def cmd_rom(args):
    rom = Path(args.path).read_bytes()
    bad = 0
    if len(rom) == ROM_SIZE:
        say("OK", f"size {len(rom):,} bytes (16 MiB)")
    else:
        say("FAIL", f"size {len(rom):,} bytes, expected {ROM_SIZE:,}")
        bad += 1
    if rom[4:8] == bytes([0x24, 0xFF, 0xAE, 0x51]):
        say("OK", "Nintendo logo data present")
    else:
        say("FAIL", "logo data missing, this is not a GBA ROM")
        bad += 1
    title = rom[0xA0:0xAC].decode("ascii", "replace").rstrip("\x00 ")
    code = rom[0xAC:0xB0].decode("ascii", "replace")
    if code.startswith("BPE"):
        region = REGIONS.get(code[3], "unknown region")
        say("OK", f"title '{title}', game code {code} ({region})")
    else:
        say("FAIL", f"game code {code!r} is not Emerald (expected BPE?)")
        bad += 1
    stored = rom[0xBD]
    calc = (-(sum(rom[0xA0:0xBD]) + 0x19)) & 0xFF
    if stored == calc:
        say("OK", f"header checksum 0x{stored:02X} matches")
    else:
        say("FAIL", f"header checksum stored 0x{stored:02X}, computed 0x{calc:02X}")
        bad += 1
    say("INFO", f"SHA-1 {hashlib.sha1(rom).hexdigest()}")
    say("INFO", "compare the SHA-1 with a No-Intro style database entry for your region")
    return 1 if bad else 0


def section_checksum(sector, sec_id):
    size = SECTION_SIZES[sec_id]
    words = struct.unpack_from(f"<{size // 4}I", sector, 0)
    total = sum(words) & 0xFFFFFFFF
    return ((total >> 16) + (total & 0xFFFF)) & 0xFFFF


def check_slot(blob, first):
    chunk = blob[first * SECTOR:(first + 14) * SECTOR]
    if chunk.count(0xFF) == len(chunk):
        return {"state": "empty", "counter": -1, "problems": []}
    problems, seen, counters = [], set(), set()
    for n in range(first, first + 14):
        sector = blob[n * SECTOR:(n + 1) * SECTOR]
        sec_id, stored, sig, counter = struct.unpack_from("<HHII", sector, 0xFF4)
        if sig != SIGNATURE:
            problems.append(f"sector {n}: bad signature 0x{sig:08X}")
            continue
        if sec_id > 13 or sec_id in seen:
            problems.append(f"sector {n}: section id {sec_id} invalid or repeated")
            continue
        seen.add(sec_id)
        counters.add(counter)
        calc = section_checksum(sector, sec_id)
        if calc != stored:
            problems.append(f"sector {n} (section {sec_id}): checksum "
                            f"stored 0x{stored:04X}, computed 0x{calc:04X}")
    if len(seen) != 14:
        problems.append(f"only {len(seen)} of 14 sections found")
    if len(counters) > 1:
        problems.append("sectors disagree on the save counter")
    counter = max(counters) if counters else -1
    return {"state": "ok" if not problems else "damaged",
            "counter": counter, "problems": problems}


def analyse_save(path):
    data = Path(path).read_bytes()
    trailer = b""
    if len(data) == SAVE_SIZE_RTC:
        data, trailer = data[:SAVE_SIZE], data[SAVE_SIZE:]
    return data, trailer


def cmd_save(args):
    data, trailer = analyse_save(args.path)
    full = Path(args.path).stat().st_size
    if len(data) != SAVE_SIZE:
        say("FAIL", f"size {full:,} bytes, Emerald needs {SAVE_SIZE:,} (Flash 128K)")
        say("INFO", "a smaller file usually means the emulator used SRAM or Flash 64K")
        return 1
    say("OK", f"size {full:,} bytes")
    if trailer:
        say("INFO", "16-byte clock trailer found, the emulator appended RTC state")
        if args.strip:
            out = Path(args.path).with_suffix(".128k.sav")
            out.write_bytes(data)
            say("OK", f"wrote trailer-free copy {out}")
    slots = [check_slot(data, 0), check_slot(data, 14)]
    for name, slot in zip("AB", slots):
        if slot["state"] == "empty":
            say("INFO", f"slot {name}: empty (all 0xFF)")
        elif slot["state"] == "ok":
            say("OK", f"slot {name}: 14/14 sections valid, counter {slot['counter']}")
        else:
            say("FAIL", f"slot {name}: damaged")
            for p in slot["problems"]:
                say("FAIL", f"  {p}")
    good = [s for s in slots if s["state"] == "ok"]
    if all(s["state"] == "empty" for s in slots):
        say("WARN", "no saved game yet, save inside the game first")
        return 2
    if not good:
        say("FAIL", "no usable save slot, restore a backup")
        return 1
    newest = "AB"[slots.index(max(good, key=lambda s: s["counter"]))]
    say("OK", f"the game will load slot {newest}")
    return 0


def cmd_backup(args):
    src = Path(args.path)
    dest = Path(args.dest)
    dest.mkdir(parents=True, exist_ok=True)
    data, _ = analyse_save(src)
    ok = len(data) == SAVE_SIZE and any(
        check_slot(data, f)["state"] == "ok" for f in (0, 14))
    tag = "ok" if ok else "suspect"
    stamp = time.strftime("%Y%m%d-%H%M%S")
    target = dest / f"{src.stem}-{stamp}-{tag}.sav"
    shutil.copy2(src, target)
    if hashlib.sha1(target.read_bytes()).digest() != hashlib.sha1(src.read_bytes()).digest():
        say("FAIL", "copy does not match the source")
        return 1
    say("OK" if ok else "WARN", f"saved {target.name}")
    good = sorted(dest.glob(f"{src.stem}-*-ok.sav"))
    for old in good[:-args.keep]:
        old.unlink()
        say("INFO", f"pruned {old.name}")
    return 0


def main():
    p = argparse.ArgumentParser(description=__doc__)
    sub = p.add_subparsers(dest="cmd", required=True)
    r = sub.add_parser("rom", help="check a ROM dump")
    r.add_argument("path")
    r.set_defaults(fn=cmd_rom)
    s = sub.add_parser("save", help="check a .sav file")
    s.add_argument("path")
    s.add_argument("--strip", action="store_true", help="write a copy without the RTC trailer")
    s.set_defaults(fn=cmd_save)
    b = sub.add_parser("backup", help="copy a save into a rotating backup folder")
    b.add_argument("path")
    b.add_argument("dest")
    b.add_argument("--keep", type=int, default=20)
    b.set_defaults(fn=cmd_backup)
    args = p.parse_args()
    sys.exit(args.fn(args))


if __name__ == "__main__":
    main()

Run the ROM check against your dump. On Windows use py in place of python3.

python3 tools/emerald_doctor.py rom roms/pokemon-emerald.gba

A clean English dump prints four OK lines and one SHA-1 line. The hash is your fingerprint. Paste it into a No-Intro style database search for your region and confirm the entry says Emerald. If the size line fails, you dumped the wrong amount of data. If the game code line fails, the file is not Emerald, which also happens when someone hands you a ROM hack with a patched header. A header checksum failure points to a damaged dump, and a damaged dump will keep producing strange behavior no matter how well you configure the emulator. Re-dump before you continue.

The script reads the standard GBA header fields, so it works on any region. The final letter of the game code tells you the language, with E for English, J for Japan, F for French, D for German, I for Italian and S for Spanish. Save files from different regional versions are not something to mix, so label your dump and your backups with the same region tag from day one.

Steps 4 to 6: Install mGBA 0.10.5 and Lock Down Its Config

Step 4: Download the official 0.10.5 build. Get mGBA from the project website, not from a mirror or a repackager. Windows and macOS users unpack or copy the build into emerald-lab/mgba. Linux users can use the official AppImage or a distribution package and point the launcher at it later. After the first start, open the Help menu, choose About, and confirm the version reads 0.10.5. If it reads something with an extra suffix, such as 0.10.5-5, you have a third-party repackage. A repackaged AppImage with that label appeared on October 22, 2026, and its own release notes describe a dependency-script update, not a Pokémon or clock fix. It may work fine, but it is not what the mGBA team ships, so it is not what you should debug against.

Skip the 0.11 development builds for now. A reply in a project forum thread about a debugger problem on 0.10.3 called that version very old and asked the reporter to retest on a 0.11 build. The advice is sound for bug hunting. It is the wrong advice for a save you care about, because development snapshots can change file handling without warning. If you want to experiment, copy your save first and test on the copy. We cover that routine in the advanced section.

Step 5: Turn on portable mode and point saves at your folder. Portable mode keeps the emulator configuration next to the executable, so a reinstall or a second user account on the machine cannot silently swap your settings. Create an empty file named portable.ini in the same folder as the mGBA executable. Then launch the emulator, open Settings, go to Paths, and set the save games folder to emerald-lab/saves. Set the save states folder to a subfolder of your choosing, such as emerald-lab/saves/states, so the two kinds of file never mix. Menu labels shift slightly between builds, so match the intent and not the exact wording.

# Windows (PowerShell)
New-Item -ItemType File "$env:USERPROFILE\emerald-lab\mgba\portable.ini"

# macOS and Linux (for the Qt binary folder you unpacked)
touch ~/emerald-lab/mgba/portable.ini

With the paths set, the emulator will write pokemon-emerald.sav into the saves folder, named after your ROM. That is why Step 2 insisted on a stable ROM name. If you prefer the default behavior of saving beside the ROM, that works too, but you must then adjust every path in the scripts. A dedicated folder is easier to back up and harder to delete by accident. If you want an automated way to start the emulator with these paths already wired in, our Pokémon emulator launcher script walkthrough shows the same idea for several systems at once.

Step 6: Boot the ROM once and change nothing else. Open the ROM from File, or start the emulator with the ROM path as an argument. Watch the Game Freak logo, the intro and the title screen. Do not start a new game yet and do not save. The point of this boot is to confirm that the dump runs, that audio and input work, and that the emulator has not silently chosen a strange configuration. Map your keyboard or controller now. Emerald needs only the D-pad, A, B, Start, Select and the shoulder buttons, which a basic pad covers easily.

Fast-forward is worth binding at this stage. It makes the opening dialogue and the long text boxes pass quickly. It does not make in-game time pass quickly, though. As far as the project documentation describes it, the clock follows your computer’s wall time, and fast-forward only speeds up emulated frames. Expect to wait real hours for berries, which is why Step 8 includes a workaround.

Steps 7 and 8: Force Flash 128K and Test the Clock

Step 7: Open Game Overrides and set the save type and the clock. mGBA identifies cartridges from a built-in database keyed on the game code, so a genuine Emerald dump usually gets the right save type and clock support automatically. Overriding them by hand costs one minute and removes the guesswork, which matters most for translated dumps, repacked dumps and ROM hacks. In the menu bar open Tools, then Game Overrides.

Set the save type to the 1 Mbit flash option. mGBA, like several other emulators, names flash chips by capacity in bits, and 1 Mbit equals 128 KiB, which is the Flash 128K type Emerald expects. Then tick the real-time clock option in the hardware list. Apply the override, close the dialog, and reset the game from the emulation menu so the change takes effect. EmuDesk keeps a troubleshooting page on mGBA games that will not save, covering GBA save types and the clock, and its advice matches this step: pick the right flash size and leave the clock enabled.

Two cautions apply. First, a wrong flash size is worse than autodetect. If you choose the 512 Kbit option, the game may still run, but only half the save area exists, and the second slot never persists. Second, an override applies to the game code, so if you later load a ROM hack built on Emerald that expects different hardware, the override can follow it into the hack. Hacks that use a larger save need their own settings. Check the hack’s readme and clear the override if it recommends autodetection.

Step 8: Set the in-game clock and run the clock test. Start a new game. Early on, the game asks you to set the clock, with the prompt tied to the wall clock in your bedroom. Enter the current local time. Emerald keeps its own record of that time and counts forward from it using the clock hardware, so the value you enter is the anchor for every later event. If you set the wrong time on purpose, as some players do to dodge tide or lottery timing, remember that all later checks drift with it.

Run three checks and write the results down. Check one is a berry. Once you get your first berry, plant it in any soft soil patch, note the real time, save in the game, and quit cleanly. Berries sprout after real-world hours, not minutes. When you reopen the game several hours later, the plant should have advanced even though the emulator was closed. That result confirms the game compared the stored time with the clock hardware and found a gap, which is exactly how a real cartridge behaves. Check two is the Shoal Cave tide. The cave floods and drains on a cycle of roughly six hours, so visiting at two different times of day should show two different water levels. Check three is the daily lottery number at the Lilycove department store, which should change after midnight on your computer’s clock.

If you cannot wait, force the issue with the system clock. Turn off automatic time sync in your operating system, move the computer clock forward 12 hours, launch the game and look at the berry. If the berry advanced, the clock path works end to end. Set the system time back and re-enable automatic sync afterward. Skipping that last part causes certificate errors, calendar glitches and failed logins in unrelated apps, so treat it as a short test and not a lifestyle. This trick relies on the emulator following the host clock, which is how mGBA is described to work. A page from Pocket Deal Radar on clock and time-event checks for the Modern Emerald hack separates real time from fake time and lists event checks, which is a useful vocabulary even outside that hack.

Clock checkWhat you doHealthy resultFailure sign
Berry growthPlant a berry, save, quit, return hours laterPlant has advanced a stage or morePlant is unchanged after many hours
Shoal Cave tideVisit at two times of day, roughly six hours apartWater level differsWater level never changes
Lilycove lotteryCheck the number before and after midnightNumber changes the next dayNumber is frozen
System clock jumpMove host time forward 12 hours with sync offBerry advances on launchNo change, clock option is off

Steps 9 and 10: Save Safely and Validate Every Sector

Step 9: Use the in-game save, then exit cleanly. Open the Start menu in the game, choose Save, confirm, and wait for the game to finish writing. The on-screen message tells you not to turn the power off, and the emulator version of that warning is simple: do not close the window until the message disappears. Then quit through the emulator menu, not by killing the process or pulling the plug on a handheld. Current setup guidance recommends a clean exit so that battery-save data held in memory gets written to storage. That advice comes from a single guide, but it matches how flash saves work, since the final write happens when the emulator flushes its buffers.

Treat save states as a convenience layer and not as your save. A state captures the full emulated machine at one instant, including the clock position, and loading an old one drags the game back to that moment while your computer clock keeps moving. For berries and tides that is mostly harmless, but it makes the game state and the date disagree in ways the real hardware never would. Keep the in-game save as the file that matters and use states only for quick retries.

Step 10: Run the save check. With the emulator closed, run the checker on the file the emulator wrote. It reads all 32 sectors, verifies the signature and checksum of the 14 sections in each slot, and tells you which slot the game will load.

python3 tools/emerald_doctor.py save saves/pokemon-emerald.sav

The command exits with 0 when at least one slot is intact, 1 when nothing usable remains, and 2 when the file is brand new and empty. That exit code is what lets the launcher script in the project section report problems without you reading every line. A healthy file after a few hours of play looks like this. The counters are examples, and yours will differ.

[OK  ] size 131,072 bytes
[OK  ] slot A: 14/14 sections valid, counter 41
[OK  ] slot B: 14/14 sections valid, counter 42
[OK  ] the game will load slot B

Read the output as a story. Two valid slots with counters one apart mean the game has been alternating normally, and the higher counter is the newer save. One valid slot and one empty slot is normal right after your first save. One valid slot and one damaged slot means the last write was interrupted and the game will quietly use the older slot. That is the moment to look at your backups, which Step 11 sets up. A file where the size line fails tells you something different. A size under 128 KiB means the emulator picked a smaller save type. Set Flash 128K again as in Step 7, work on a copy of the file, and play from a fresh slot or restore a proper backup.

Steps 11 to 13: Backups, Save States, and Moving Saves

Step 11: Add rotating backups. The backup subcommand copies your save into the backups folder with a timestamp, checks that the copy matches byte for byte, and tags the file ok or suspect depending on whether at least one slot validates. It keeps the newest 20 ok files by default and never deletes a suspect file, so a run of bad saves cannot push your last good backup out of the rotation. Run it by hand to see the format.

python3 tools/emerald_doctor.py backup saves/pokemon-emerald.sav backups --keep 20
[OK  ] saved pokemon-emerald-20261030-184512-ok.sav

Run it before every session and not after, because a backup taken before you play captures the last known good state. If a session corrupts something, the file you need is the one from just before it started. Our walkthrough on Pokémon emulator save backups goes deeper on retention schedules, and the Ludusavi emulator save backup tutorial shows how to add a second, off-machine copy so a dead drive cannot take your saves with it.

Step 12: Run a restore drill. A backup you have never restored is a hope, not a backup. Close the emulator, copy one of the ok backups over saves/pokemon-emerald.sav, start the game, and confirm that it loads and that the Continue screen shows the play time you expect. Then run the save check again. Do this once now, while nothing is at stake, and you will not panic the first time a real save goes wrong. Also confirm the restored file keeps the exact name the emulator expects, because a backup named with a timestamp does nothing until it is copied back under the ROM’s name.

Step 13: Move saves between emulators and hardware without breaking them. This is where the file size matters. The raw flash save is 128 KiB. If your emulator appends a 16-byte clock record, as one documented integration reports for mGBA, the file grows to 131,088 bytes, and another tool may refuse it or silently ignore the extra bytes. One importer is documented to accept a canonical 128 KiB save and to recognize and remove the trailer when its size and clock fields check out. When you need a plain file, let the checker create it.

python3 tools/emerald_doctor.py save saves/pokemon-emerald.sav --strip
[OK  ] size 131,088 bytes
[INFO] 16-byte clock trailer found, the emulator appended RTC state
[OK  ] wrote trailer-free copy saves/pokemon-emerald.128k.sav
[OK  ] slot A: 14/14 sections valid, counter 41
[OK  ] slot B: 14/14 sections valid, counter 42
[OK  ] the game will load slot B

The stripped copy is what you hand to other tools. A flash cartridge such as the one covered in our EverDrive GBA Pro Pokémon setup usually expects a plain 128 KiB file, and so do most save editors. Going the other way, copying a plain 128 KiB file into mGBA works, because the emulator reads the standard flash image. Two rules prevent grief. Always copy, never move, so the original stays in your backups folder. And never let two emulators write to the same file at once, which is a recipe for the half-written slot problem described earlier.

What a Healthy Run Looks Like

After the 13 steps, every session follows the same short loop, and the output tells you whether things are fine. A clean session produces a backup line before play and a save check after play. Here is the combined output from the launcher in the project section.

[OK  ] saved pokemon-emerald-20261030-190201-ok.sav
(emulator runs, you play, you save in game, you quit cleanly)
[OK  ] size 131,072 bytes
[OK  ] slot A: 14/14 sections valid, counter 43
[OK  ] slot B: 14/14 sections valid, counter 42
[OK  ] the game will load slot A

Notice the counters. Before this session slot B held the newest save at counter 42, so the game wrote the older slot A and gave it counter 43. That alternation is the signature of a healthy flash save. If you ever see both counters stuck at the same value after you played and saved, the emulator did not write, and you should suspect the save type or a read-only folder.

Outside the terminal, a healthy setup feels boring. Continue shows the right play time, berries advance while the emulator is closed, the tide moves, and a restore from backup works on the first try. If any of those fail, the troubleshooting section below maps the symptom to a fix. Beyond that, keep an eye on the file timestamps in the saves folder. A save file that never changes its modified time while you are playing is the earliest visible sign of a path or permissions problem.

Common Pitfalls That Corrupt Emerald Saves

Most lost Emerald saves come from habits and not from bugs. These six cause the bulk of them.

  1. Killing the emulator mid-save. Closing the window while the game is writing leaves a half-written slot. The game falls back to the older slot, and you lose recent progress without an error. Wait for the save message to finish and quit from the menu.
  2. Relying on save states alone. States depend on the exact emulator build. Update mGBA and an old state may refuse to load, taking your only copy of the progress with it. Always keep a real in-game save.
  3. Renaming the ROM after you start playing. The save name follows the ROM name. Rename the ROM and the emulator creates a new empty save, which looks exactly like data loss. Rename the old save to match, and keep the name stable.
  4. Putting the saves folder inside a cloud-sync directory. Sync clients lock or rewrite files while the emulator is still using them. Back up to the cloud from the backups folder instead and keep the live save on local disk.
  5. Trusting a repackaged build. A third-party AppImage labelled 0.10.5-5 is not an upstream release. Use the official 0.10.5 download for your main save and keep experimental builds on copies.
  6. Forcing the wrong save type on a ROM hack. The override from Step 7 follows the game code. A hack that needs a different save size will misbehave under a Flash 128K override, so read the hack notes and clear the override when they say to.

One more habit deserves a mention because it hides well. Many players run the emulator from a ZIP file or a temporary folder, and the save file then lands wherever the emulator happens to be writing that day. Always launch from the project folder and keep the scripts on the same drive, so the paths you test are the paths you use.

Troubleshooting: 10 Fixes for Emerald Save and Clock Problems

Work through these in order. Each starts with what you see, then names the cause and the fix. If you want more Pokémon emulator walkthroughs while you debug, the gaming section collects them.

  1. The game says there is no save after a restart. Check that pokemon-emerald.sav exists in the saves folder and that its modified time changed after you saved. If the file sits beside the ROM instead, your Paths setting from Step 5 did not stick. Fix the path and copy the file across.
  2. The save file is smaller than 128 KiB. The emulator guessed a smaller save type. Reapply the 1 Mbit flash override from Step 7, reset the game, play from a copy, and run the checker.
  3. The checker reports a checksum mismatch in one slot. The game can still load the other slot, so keep playing only after you copy the file elsewhere. Restore the newest ok backup if you need the lost progress, and note when the damage happened.
  4. Both slots fail. Stop playing. Copy the file to safety, restore the newest ok backup, and run the checker on the restored copy. If every backup is marked suspect, the problem predates your backups, and the next step is a different dump or save source.
  5. Berries never grow. The clock option is off or the in-game time is wrong. Reopen Game Overrides, tick the real-time clock, reset the game, and confirm with the system clock jump from Step 8. Also check the in-game clock still holds a sensible time.
  6. The tide or lottery never changes. Same cause as the berries. If the checks pass on a new test file but fail on your main save, the main save probably recorded the wrong time. Reset the in-game clock from the bedroom clock.
  7. The emulator refuses to load the ROM. Run the ROM check. A size or header failure means a bad dump. A game code that does not start with BPE means you picked the wrong file. Re-dump from your cartridge.
  8. A save from another tool will not load. The file may carry the 16-byte clock record or lack it. Use the strip option to produce a plain 128 KiB copy, or append nothing and let the emulator create its own record on first save.
  9. The controller works in the menu but not in the game, or not at all on Linux. A Linux gamepad detection issue was reported on October 12, 2026 and assigned to the 0.11.1 milestone, with a note that it looked fixed in development builds. Until a stable release ships, bind keys on the keyboard or test the controller in a development build on a copy of your save.
  10. The checker will not run. On Windows use py instead of python3. If Python is missing, install a current 3.x release and reopen the terminal. A syntax error on an older interpreter means you are below 3.9.

If none of these match, collect three facts before asking for help anywhere: the exact mGBA version from the About dialog, the byte size of the save file, and the full checker output. Those three lines answer most questions in the first reply.

Advanced Tips for Long Emerald Playthroughs

Once the basics hold, a few extras make long runs safer and more flexible. Each of these is optional, and none of them is needed to finish the tutorial.

  • Schedule the backup. The launcher backs up at session start, but a scheduled job catches sessions you forgot to launch through it. Use Task Scheduler on Windows or a cron entry on macOS and Linux to run the backup command every hour.
  • Test development builds on a copy. Make a second project folder, copy the save and ROM into it, and run a 0.11 development build there. If something breaks you lose nothing. If it works, compare the checker output between the two builds before you trust it.
  • Inspect and edit on a copy only. A save editor can show your party, boxes and items, which helps when you suspect corruption. Our PKHeX guide to editing Pokémon saves explains the workflow, and the rule is the same as everywhere here: work on a copy, never the live file.
  • Pair saves with cheats carefully. Cheats that write to memory can produce data the game then saves, and a bad code can damage a slot. If you use them, read our Pokémon Emerald cheats on mGBA walkthrough and back up before every cheat session.
  • Know your alternatives. If mGBA is not an option on your device, our GBA emulator comparison ranks the main choices, including iPhone options. The save format is a standard flash image in most cases, so the checker still applies once you export the file.
  • Keep a hash list. Store the SHA-1 of your ROM and of each long-term backup in a text file. When a file changes unexpectedly, the hash tells you in a second.

One last tip concerns hardware time. If you play on a handheld or a small Linux device with no battery-backed clock, the device time can reset to a default after a power loss, and the game clock then jumps with it. Make sure the device syncs its time over the network at boot, or the berries and tides will follow a wrong date.

The Full Working Project

The finished project is the folder you built in Step 1 plus the checker script and one launcher per platform. The tree below shows where everything lives.

emerald-lab/
  roms/
    pokemon-emerald.gba        (your own dump)
  saves/
    pokemon-emerald.sav        (live save, written by mGBA)
    states/                    (save states, optional)
  backups/
    pokemon-emerald-YYYYMMDD-HHMMSS-ok.sav
  tools/
    emerald_doctor.py          (from Step 3)
    launch.sh                  (macOS and Linux)
    launch.ps1                 (Windows)
  mgba/
    mGBA executable
    portable.ini

Save this as tools/launch.sh on macOS or Linux and make it executable with chmod +x. Set MGBA_BIN if your emulator binary has a different name or path. On macOS the executable sits inside the app bundle.

#!/usr/bin/env bash
set -euo pipefail
LAB="$HOME/emerald-lab"
MGBA="${MGBA_BIN:-mgba-qt}"
SAVE="$LAB/saves/pokemon-emerald.sav"
DOC="$LAB/tools/emerald_doctor.py"

if [ -f "$SAVE" ]; then
  python3 "$DOC" backup "$SAVE" "$LAB/backups" --keep 20
fi

"$MGBA" "$LAB/roms/pokemon-emerald.gba"

if [ -f "$SAVE" ]; then
  python3 "$DOC" save "$SAVE" || echo "Check the output above before you play again."
fi

Windows users save this as tools\launch.ps1. It waits for the emulator to exit, so the save check runs at the right moment.

$Lab  = "$env:USERPROFILE\emerald-lab"
$Save = "$Lab\saves\pokemon-emerald.sav"
$Doc  = "$Lab\tools\emerald_doctor.py"

if (Test-Path $Save) { py $Doc backup $Save "$Lab\backups" --keep 20 }

Start-Process -Wait "$Lab\mgba\mGBA.exe" -ArgumentList "`"$Lab\roms\pokemon-emerald.gba`""

if (Test-Path $Save) { py $Doc save $Save }

Run the launcher instead of opening the emulator directly. Each session then backs up first, plays, and verifies afterward. To confirm the whole chain, do a dry run. Start a new test game, set the clock, save, quit, and read the checker output. Then start again, confirm a second backup appears, and restore one as in Step 12. When all three pass, the project is done. From here on the only thing you do differently from a normal session is start the game through the launcher.

The checker is deliberately small. It checks structure and checksums, which catches truncation, wrong save types, interrupted writes and flipped bytes, and it does not try to understand your party or items. That keeps it dependable across emulators and language versions. If you extend it, keep the rule that it never modifies the live save, and make any future repair feature write to a new file.

Frequently Asked Questions

Does Pokémon Emerald need the real-time clock to be playable? No. The main story, gyms and Battle Frontier run without it. Berry growth, the Shoal Cave tide cycle and the daily lottery depend on the clock, so skipping it removes those features and nothing else.

Which save type does Emerald use in mGBA? Flash 128K, which is 128 KiB. In menus that list chip sizes in bits, look for the 1 Mbit flash option. A smaller file is the sign of the wrong choice.

What is the newest stable mGBA right now? As of October 30, 2026, mGBA 0.10.5 is the newest numbered stable release you can confirm. Version 0.11 builds exist as development snapshots, and the 0.11.1 milestone has no due date.

Why is my save 131,088 bytes? One documented integration reports that mGBA can append a 16-byte clock record to the save. The raw flash image is the first 128 KiB. Use the strip option in the checker to produce a plain copy for other tools.

Can I move my Emerald save between mGBA and another emulator? Usually yes, because the save is a standard flash image. Copy the file, strip the clock record if the target tool is strict about size, and keep the original in your backups folder. Never let two programs write to the same file.

Is it legal to use an emulator for Emerald? The emulator is legal software. The game file needs to come from a cartridge you own, dumped by you, and kept private. This tutorial does not link to ROM sources.

Do I need Python, or can I skip the script? You can play without it. The script adds ROM verification, sector-level save checks and rotating backups, which are the parts that rescue a save after something goes wrong. It needs only a standard Python 3 install and no extra packages.

Marcus Chen

Marcus Chen

Gaming & Consumer Tech Editor

Marcus Chen is a senior editor at Tech Insider, where he leads coverage of the US online gaming market, including sweepstakes and social casinos, alongside consumer technology. He evaluates operators on their published terms, licensing and RNG certifications, stated redemption policies, and corroborating independent reporting, and writes plainly about what the evidence supports. Tech Insider does not run first-party money tests and does not gamble with reader funds. Marcus has reported on the technology and online-gaming industries for more than a decade.

View all articles