PokÃĐmon HeartGold and SoulSilver run best on melonDS, the free open-source Nintendo DS emulator, and the official build to use today is melonDS 1.1. As of October 27, 2026, no newer official standalone release exists, and the project says version 1.2 ships when its lead developer is happy with it. That makes this the right moment for a clean PokÃĐmon HeartGold emulator setup: the target is stable, and the forks are easy to tell apart from the real thing.
This tutorial takes 13 steps and about 45 minutes. If you have never configured the emulator, our general melonDS guide for PokÃĐmon covers the basics. This one goes narrower. The Johto remakes lean hard on the touchscreen, the real-time clock and long play sessions, so we tune for exactly those, then finish with a Python companion script that validates your files, backs up your save before and after every session, and launches the game.
Everything here assumes you play from a cartridge you own. We never link to ROM downloads, and the legal section explains why that matters for your safety as well as your conscience.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
Why melonDS Is the Right PokÃĐmon HeartGold Emulator in 2026
melonDS aims at fast and accurate Nintendo DS emulation, and its feature list reads like a checklist for these two games. The project’s own homepage lists a JIT recompiler for speed, an OpenGL renderer with 3D upscaling, real-time clock support, microphone and lid emulation, joystick support, savestates and several screen layout modes. Each item maps to something HeartGold or SoulSilver does constantly.
Take the touchscreen first. The PokÃĐgear, the PokÃĐathlon minigames and most menus live on the bottom screen, so a layout that keeps both screens visible and a mouse that behaves like a stylus decide whether the game feels playable. Then the clock. Johto runs on time of day and day of the week, from morning and night encounters to the Bug-Catching Contest that only runs on certain days. An emulator without a working clock would flatten half the game. melonDS reads your computer’s clock, which is the behavior you want.
The 3D upscaling matters for a simpler reason. The native DS resolution is tiny by modern standards, and HeartGold’s overworld is one of the better candidates for scaling because its sprites sit on a 3D map. Rendering that map at a higher internal resolution sharpens it without touching the 2D layers. If you want the broader context of how melonDS stacks up against other DS options, our ranking of DS emulators by device lays out the alternatives.
Where melonDS development stands in October 2026
The official project is healthy but slow. Its repository was updated as recently as October 21, 2026, and the lead developer says on the melonDS site that melonDS 1.2 will be released when they are satisfied with it. No release date is confirmed. None of that changes how the current build behaves, but it explains why you should not wait for 1.2. The newest official standalone desktop release that can be confirmed is melonDS 1.1.
Because the emulator is open source, forks appear quickly, and a few of them use names close enough to cause mistakes. The table below separates the builds you will run into.
| Build | What it is | Use it for HeartGold and SoulSilver? |
|---|---|---|
| Official melonDS desktop (1.1) | The upstream project on Windows, macOS and Linux | Yes. This is the first choice and the one this guide uses. |
| melonDS Android | A separate Android port of the emulator | Yes, for phones. Settings differ from desktop, so treat it as its own setup. |
| WatermelonDS | A separate fork with its own release line | Only if you want its extras. It is not the official melonDS. |
| melonDS Project PM | An unofficial build made for a multiplayer bridge | No. It exists for a specific multiplayer use case. |
| Wii-DS Link builds | An unofficial fork built around Dolphin interaction | No. It is an unofficial fork, not part of upstream melonDS. |
| Third-party AppImage or repackaged builds | Community packaging of an upstream release | Only if you trust the packager. Prefer the official download. |
One reported detail is worth a hedge. Third-party trackers describe WatermelonDS 0.8.0-rc3 and a Wii-DS Link beta from October 20. These are release candidates and betas from other people, so none of them replaces the official build for a long single-player run. If you want to compare the forks against 3DS-era options, our mGBA, WatermelonDS and Azahar comparison goes through them one by one.
A final point on the games themselves. PokÃĐmon’s official game page describes HeartGold and SoulSilver as Nintendo DS and Nintendo DSi titles that revisit the Johto adventure of Gold and Silver. As of this writing no HeartGold or SoulSilver remake, remaster or re-release has been confirmed for a current Nintendo platform. If you want the original Johto games on their native hardware generation, our SameBoy setup for Gold, Silver and Crystal covers those, and this guide handles the DS remakes.
Prerequisites and Versions
You need less than most PokÃĐmon SoulSilver emulator tutorials ask for. The emulator is a single download, the game comes from your own cartridge, and the only extra tool is Python for the companion script. The table lists every component with the version this guide was written against.
| Component | Version or requirement | Notes |
|---|---|---|
| melonDS | 1.1, official desktop build | Free, GPL-3.0. Do not use a fork for this guide. |
| Operating system | 64-bit Windows, macOS or Linux | Commands below show Windows paths, with notes for the others. |
| Python | 3.10 or newer | Used only for the companion script. Standard library only, no packages to install. |
| Graphics | A GPU and driver with working OpenGL | Needed for the OpenGL renderer and 3D upscaling. |
| Game | Your own HeartGold or SoulSilver cartridge | Any region. The script accepts the common region codes. |
| Cartridge dumper | GodMode9 on a 3DS with custom firmware, or an equivalent tool | Dumps your cartridge to an .nds file. |
| BIOS and firmware | bios7.bin, bios9.bin, firmware.bin from your own DS | Recommended for accuracy. See the legal section. |
| Input | Keyboard and mouse, with an optional gamepad | The mouse stands in for the stylus. |
Budget your 45 minutes like this. Dumping the files takes the longest if you have never done it, usually 15 to 20 minutes including the console setup. Installing melonDS and saving the script takes five. Configuration, input mapping and the first in-game save take another 15. The rest is slack for the troubleshooting section.
One more planning note. Pick a folder that is not inside a cloud-sync directory such as OneDrive or Dropbox. Sync clients lock files while uploading, and a locked save file at the moment the emulator tries to write it is one of the classic ways to lose progress. If you want cloud protection, sync the backups folder only, which the project in this guide keeps separate on purpose.
Staying Legal: Dump Your Own Cartridge
Emulators are legal software. ROM files are the part that carries risk. The safe route, and the only one this guide supports, is to dump the cartridge you bought. You do that once, keep the file for personal backup and play, and never share it. No official Nintendo documentation covers running HeartGold or SoulSilver in melonDS, so the responsibility for sourcing the files sits with you.
There is also a practical reason to skip download sites. Files from unknown uploaders are sometimes patched, trimmed, renamed or bundled with extras, and a corrupted header can produce the kind of bugs that look like emulator problems for hours. A fresh dump from your own cartridge removes that variable entirely. When you later run the validation script in Step 6, a clean dump should pass every check on the first try.
Same rule for the DS BIOS and firmware. Community setup notes consistently tell users to bring BIOS and firmware dumps from their own console, and that is the approach we follow. If you do not own a DS-family console, read the Howto and FAQ page linked from the melonDS homepage to see what the current build supports without them before you start hunting for files elsewhere.
Steps 1 to 3: Dump the Cartridge, BIOS and Firmware
Step 1: Identify your cartridge. Flip the cartridge and read the code on the back label. It looks like NTR-IPKE-USA for a US HeartGold or NTR-IPGE-USA for a US SoulSilver. The four letters after the hyphen are the game code the script will check later. The first three are IPK for HeartGold and IPG for SoulSilver, and the fourth letter is the region: E for North America, P for Europe, J for Japan, D for German, F for French, I for Italian, S for Spanish and K for Korean releases. Write yours down.
Step 2: Dump the cartridge. On a 3DS with custom firmware, GodMode9 mounts the inserted game card as a drive. Open the game card drive, select the .nds image, and choose the option that copies it to the gm9/out folder on your SD card. Move the file to your PC and rename it to pokemon_heartgold.nds or pokemon_soulsilver.nds. If you also want to bring existing progress, the same tool can dump the cartridge save, which becomes your .sav file. Follow your dumper’s own documentation for the exact menu names, because they change between versions.
Step 3: Dump BIOS and firmware. You want three files from a DS-family console: the ARM7 BIOS, the ARM9 BIOS and the firmware. Rename them bios7.bin, bios9.bin and firmware.bin. The sizes are fixed for the two BIOS files, 16,384 bytes for ARM7 and 4,096 bytes for ARM9, and the firmware varies by console model. The script checks all three, so a wrong dump fails loudly instead of silently misbehaving at the title screen.
Put everything in one project folder with this layout. You will create the melonDS folder in the next section and the script in Step 5.
hgss-melonds/
hgss_companion.py
hgss.json
melonDS/ <- extracted emulator
bios/
bios7.bin
bios9.bin
firmware.bin
roms/
pokemon_heartgold.nds
backups/ <- created automatically
If you also run PokÃĐmon Platinum on melonDS, reuse the same bios folder. Keep one ROM per project folder, though. The script ties its backups to the ROM filename, which keeps two games from sharing a save history.
Steps 4 to 6: Install melonDS and Validate Everything With a Script
Step 4: Install melonDS 1.1. Open the Downloads page linked from the official melonDS site and grab the stable 1.1 build for your platform. On Windows you get a zip, so extract it into the melonDS folder from the layout above. There is no installer and no registry entry. On macOS, drag the app to the project folder, and the executable then lives at melonDS.app/Contents/MacOS/melonDS. On Linux, use the official archive or your distribution’s package, and set the path in the config file below. Avoid nightly builds and forks unless a later step tells you otherwise.
Step 5: Save the companion script. Create hgss_companion.py in the project folder with the code below. It uses only the Python standard library. It validates the emulator path, BIOS and firmware sizes, the ROM header and the save file, and it provides backup, restore and launch commands. The next section explains how each part works.
#!/usr/bin/env python3
"""HGSS companion for melonDS: validate files, back up saves, launch."""
import argparse
import csv
import hashlib
import json
import shutil
import subprocess
import sys
import time
from datetime import datetime
from pathlib import Path
ROOT = Path(__file__).resolve().parent
CONFIG = ROOT / "hgss.json"
DEFAULTS = {
"melonds": "melonDS/melonDS.exe",
"rom": "roms/pokemon_heartgold.nds",
"bios7": "bios/bios7.bin",
"bios9": "bios/bios9.bin",
"firmware": "bios/firmware.bin",
"backups": "backups",
"keep": 30,
}
BIOS_SIZES = {"bios7": 16384, "bios9": 4096}
FIRMWARE_SIZES = {131072, 262144, 524288}
REGIONS = "EPJDFISK"
HGSS_CODES = {}
for region in REGIONS:
HGSS_CODES["IPK" + region] = "HeartGold"
HGSS_CODES["IPG" + region] = "SoulSilver"
def load_config():
cfg = dict(DEFAULTS)
if CONFIG.exists():
cfg.update(json.loads(CONFIG.read_text(encoding="utf-8")))
return cfg
def path_of(cfg, key):
return (ROOT / cfg[key]).resolve()
def crc16(data):
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
return crc
def read_header(rom):
with rom.open("rb") as fh:
head = fh.read(0x200)
if len(head) < 0x200:
raise ValueError("file is smaller than an NDS header")
return {
"title": head[0x00:0x0C].split(b"\0")[0].decode("ascii", "replace"),
"code": head[0x0C:0x10].decode("ascii", "replace"),
"stored_crc": int.from_bytes(head[0x15E:0x160], "little"),
"real_crc": crc16(head[0x000:0x15E]),
"size": rom.stat().st_size,
}
def report(level, text):
print("[%-4s] %s" % (level, text))
return level == "FAIL"
def cmd_check(cfg):
failed = False
exe = path_of(cfg, "melonds")
failed |= report("ok" if exe.exists() else "FAIL", "emulator: %s" % exe)
for key, want in BIOS_SIZES.items():
p = path_of(cfg, key)
if not p.exists():
report("warn", "%s missing (melonDS can fall back to its built-in BIOS)" % key)
elif p.stat().st_size != want:
failed |= report("FAIL", "%s is %d bytes, expected %d" % (key, p.stat().st_size, want))
else:
report("ok", "%s is %d bytes" % (key, want))
fw = path_of(cfg, "firmware")
if not fw.exists():
report("warn", "firmware missing (direct boot still works)")
elif fw.stat().st_size not in FIRMWARE_SIZES:
failed |= report("FAIL", "firmware is %d bytes, not a known dump size" % fw.stat().st_size)
else:
report("ok", "firmware is %d bytes" % fw.stat().st_size)
rom = path_of(cfg, "rom")
if not rom.exists():
return failed | report("FAIL", "ROM not found: %s" % rom)
try:
h = read_header(rom)
except ValueError as err:
return failed | report("FAIL", "ROM unreadable: %s" % err)
game = HGSS_CODES.get(h["code"])
if game:
report("ok", "ROM is Pokemon %s (game code %s, title %s)" % (game, h["code"], h["title"]))
else:
failed |= report("FAIL", "game code %s is not HeartGold or SoulSilver" % h["code"])
if h["stored_crc"] == h["real_crc"]:
report("ok", "header checksum matches (%04X)" % h["real_crc"])
else:
report("warn", "header checksum differs (%04X vs %04X), re-dump if the game misbehaves" % (h["stored_crc"], h["real_crc"]))
report("ok", "ROM size %.1f MB" % (h["size"] / 1048576))
sav = rom.with_suffix(".sav")
report("ok" if sav.exists() else "warn", "save file: %s" % (sav if sav.exists() else "not created yet, save once in game"))
return failed
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def backup_dir(cfg):
d = path_of(cfg, "backups") / path_of(cfg, "rom").stem
d.mkdir(parents=True, exist_ok=True)
return d
def cmd_backup(cfg, tag="manual"):
sav = path_of(cfg, "rom").with_suffix(".sav")
if not sav.exists():
print("no save file yet, nothing to back up")
return False
while time.time() - sav.stat().st_mtime < 2:
time.sleep(0.5)
d = backup_dir(cfg)
copies = sorted(d.glob("*.sav"))
if copies and sha(copies[-1]) == sha(sav):
print("save unchanged since %s, skipped" % copies[-1].name)
return False
name = "%s-%s.sav" % (datetime.now().strftime("%Y%m%d-%H%M%S"), tag)
shutil.copy2(sav, d / name)
for old in sorted(d.glob("*.sav"))[: -int(cfg["keep"])]:
old.unlink()
print("backed up to %s" % (d / name))
return True
def cmd_list(cfg):
for i, p in enumerate(sorted(backup_dir(cfg).glob("*.sav"))):
print("%3d %s %6d bytes" % (i, p.name, p.stat().st_size))
def cmd_restore(cfg, name):
d = backup_dir(cfg)
pick = d / name if name else (sorted(d.glob("*.sav")) or [None])[-1]
if pick is None or not pick.exists():
print("no matching backup")
return 1
cmd_backup(cfg, "pre-restore")
shutil.copy2(pick, path_of(cfg, "rom").with_suffix(".sav"))
print("restored %s" % pick.name)
return 0
def cmd_launch(cfg):
if cmd_check(cfg):
print("fix the FAIL lines first")
return 1
cmd_backup(cfg, "pre")
start = time.time()
subprocess.run([str(path_of(cfg, "melonds")), str(path_of(cfg, "rom"))])
minutes = (time.time() - start) / 60
cmd_backup(cfg, "post")
log = ROOT / "sessions.csv"
new = not log.exists()
with log.open("a", newline="") as fh:
w = csv.writer(fh)
if new:
w.writerow(["started", "minutes"])
w.writerow([datetime.fromtimestamp(start).isoformat(timespec="seconds"), "%.1f" % minutes])
print("session: %.1f minutes" % minutes)
return 0
def main():
ap = argparse.ArgumentParser(description=__doc__)
sub = ap.add_subparsers(dest="cmd", required=True)
for name in ("check", "backup", "list", "launch"):
sub.add_parser(name)
rs = sub.add_parser("restore")
rs.add_argument("name", nargs="?")
args = ap.parse_args()
cfg = load_config()
if args.cmd == "check":
return 1 if cmd_check(cfg) else 0
if args.cmd == "backup":
cmd_backup(cfg)
return 0
if args.cmd == "list":
cmd_list(cfg)
return 0
if args.cmd == "restore":
return cmd_restore(cfg, args.name)
return cmd_launch(cfg)
if __name__ == "__main__":
sys.exit(main())
Then create hgss.json next to it. The script falls back to defaults for any key you leave out, so you only list what differs. On Windows with the layout above, the defaults already match, and you can skip the file entirely. On macOS or Linux, point melonds at your executable.
{
"melonds": "melonDS/melonDS",
"rom": "roms/pokemon_heartgold.nds",
"keep": 30
}
Step 6: Run the validator. Open a terminal in the project folder and run the check command. A passing run prints one ok line per item, and any FAIL line stops the launcher later, so fix those first.
python hgss_companion.py check
The warn lines are informational. A missing BIOS is a warning because melonDS can boot without it in direct mode, and a missing save is a warning because the file only appears after your first in-game save. A header checksum mismatch is also a warning, because a trimmed or modified dump can differ from the original and still run. A FAIL means something is wrong enough to stop: the emulator is not where the config says, a BIOS file has the wrong size, or the ROM header names a different game.
Steps 7 to 9: Configure Boot Mode, Video and Audio
Step 7: Point melonDS at your files and pick a boot mode. Launch melonDS once, open the Config menu, and choose the emulator settings dialog. In the DS-mode section, set the three file paths to your bios folder. Then decide how the game starts. Direct boot skips the DS firmware menu and jumps straight into the game, which is what most players want for HeartGold. Booting through firmware shows the DS start screen first, which helps only when you want to check the firmware itself or use features that depend on it. Start with direct boot.
While you are in that dialog, enable the JIT recompiler if the option is present for your platform. A community setup document reviewed for this guide recommends the desktop JIT for patched HeartGold and SoulSilver builds, and the project homepage lists the JIT recompiler as a core feature. It is the single biggest speed lever on a modest laptop. Turn it off only if you see crashes that disappear without it, which the troubleshooting section covers.
Step 8: Set up video. Open the video settings and pick the OpenGL renderer. Then raise the internal 3D resolution. The same community document suggests a range of two to four times native, and two times is a safe starting point for integrated graphics. Enable VSync to prevent tearing during camera scrolls. For screen layout, choose a vertical stack for a windowed session or the side-by-side layout on an ultrawide monitor, and keep the screen sizing even unless you want the touch screen smaller.
The same document also recommends a dual-window layout, which puts each screen in its own window. That helps on a second monitor and for streaming, and it hurts nothing else, so try it after the basic layout works. Remember that scaling affects only the 3D layer. Menus, text and the PokÃĐgear stay at native sharpness because they are 2D, and that is a limit of the hardware design rather than an emulator flaw.
Step 9: Set up audio. Keep the volume moderate at first, because the DS audio mixes loudly in battle themes. If you hear crackling, raise the audio latency slightly before touching anything else. Leave the microphone input on its blank or no-input option. HeartGold and SoulSilver do not need your microphone for normal play, and a noisy input device can cause stray inputs in other DS titles you may run later.
Use the table as a quick reference. These are starting points, not laws, and the next steps note where to adjust.
| Setting | Suggested starting value | Why it helps in HeartGold or SoulSilver |
|---|---|---|
| Boot mode | Direct boot | Skips the firmware menu and starts the game immediately. |
| BIOS and firmware | Your own dumps, paths set | Matches real hardware behavior more closely. |
| JIT recompiler | On for desktop | The largest speed gain, important on laptops. |
| Renderer | OpenGL | Required for 3D upscaling. |
| 3D resolution | 2x native | Sharper overworld without a heavy GPU cost. Raise it later. |
| VSync | On | Prevents tearing while the map scrolls. |
| Screen layout | Vertical or side by side | Keeps the map and the touch screen visible together. |
| Microphone | No input | The game does not need it, and stray noise can interfere. |
Steps 10 and 11: Keyboard, Mouse and Controller for a Touch-Heavy Game
Step 10: Map the keyboard. Open the input and hotkey configuration and bind the DS buttons to keys you can reach without looking. The DS has A, B, X, Y, L, R, Start, Select and the directional pad. In HeartGold and SoulSilver, X opens the main menu, Y fires the registered item, and B runs when held. Put the pad on WASD or the arrow keys and place A, B, X and Y on a cluster you can hit with your other hand. If you have played PokÃĐmon on a keyboard before, copy that layout so your muscle memory transfers.
Touch is the part people forget. The mouse acts as the stylus, so a left click taps the bottom screen. The PokÃĐgear, the item bag shortcuts and the PokÃĐathlon events all expect taps and drags, and a cursor that jumps outside the touch screen window during a minigame will cost you a medal. If the layout allows it, keep the cursor confined to the bottom screen during play. A few tapping habits help. Click and hold for drags rather than clicking twice, and keep the cursor steady while a screen transition plays.
Step 11: Add a controller and hotkeys. A gamepad covers the main buttons well, and melonDS lists joystick support among its features. A gamepad cannot replace the stylus, though, so keep the mouse within reach even on a controller setup. Then set hotkeys for the things you will use constantly: fast forward for long walks and egg hatching, a save state slot, a load state slot, and full screen. Pick keys that you cannot hit by accident while playing, since a stray fast-forward press during a battle ruins timing.
Local wireless deserves a short mention. The melonDS homepage marks Wi-Fi, including local multiplayer, as work in progress, which means trades and battles between two instances can work but deserve patience. We cover that workflow in detail in our melonDS multiplayer guide for trading PokÃĐmon. For a single-player HeartGold run, you can skip it and come back later.
One accessibility option is worth knowing even if you never need it. Many players run a vertical layout with the touch screen at reduced size and the map larger, which approximates holding the DS upright like a book. The PokÃĐgear has big buttons, so a smaller touch screen costs little, and you gain a bigger map. Try it for an hour before deciding.
Step 12: Saves, Save States and the Real-Time Clock
Step 12: Create your first in-game save and learn the difference between the two save systems. HeartGold and SoulSilver keep progress in battery-style save data, the same kind a real cartridge writes when you choose Save from the menu. melonDS stores this as a .sav file, and by default it sits next to the ROM with the same name. That file is your real progress. Save states are different. They freeze the entire emulator, including memory, and they depend on the exact emulator version. A state made in one build may not load in another, so treat states as quick checkpoints and the .sav file as your permanent record.
Play through the opening in Johto until the game lets you save, open the menu with X, and save once. Then close melonDS and confirm that a .sav file appeared beside the ROM. If it did not, check the emulator’s save-file path setting, because it is configurable and the script expects the default location. The script’s check command reports the save status so you do not have to guess.
The clock. The game asks you to set the date and time on a fresh start, and melonDS supplies the clock from your computer. In practice that means the in-game time follows your real time, so morning, day and night encounters and the contest days line up with your actual week. Do not change your system clock to skip waiting. Time-based events are tied to the stored clock, and changing it back and forth can leave events in odd states. If you must test a time-based event, use a copy of your save.
Other pitfalls hide here too. A laptop that sleeps with the emulator running can produce a large time jump, and an emulator closed by force during a write can corrupt the save. Both are reasons to automate backups rather than trust habits. If you want a different launcher design for several games at once, our PokÃĐmon emulator launcher script guide shows a multi-game approach, while this guide keeps one game and adds save protection on top.
One last hardware note. The original cartridges shipped with a PokÃĐwalker pedometer accessory that links by infrared. That accessory needs its own hardware, so plan to skip its features in an emulator. Everything else in the main story and the post-game plays through normally, and you lose nothing required to finish the game.
Step 13: The Complete Working Project in Daily Use
Step 13: Run the game through the companion script. From now on, start every session with the launch command instead of opening your PokÃĐmon HeartGold emulator directly. The script validates the files, backs up the save, runs the emulator and waits for it to exit, then backs up again and logs the session length. If anything is wrong before the game starts, it tells you and stops.
python hgss_companion.py launch
Here is what each part of the script does, in the order you would meet it.
- Configuration. DEFAULTS holds every path, and hgss.json overrides only what you list. Paths resolve relative to the script, so you can move the whole folder to a new drive without editing anything.
- Header reading. read_header opens the ROM and reads the first 512 bytes. The title sits at the start, the four-letter game code at offset 12, and a stored checksum at offset 350. The script recomputes that checksum with a CRC-16 and compares the two.
- Game-code table. HGSS_CODES builds every region variant from the IPK and IPG prefixes, so a European or Japanese cartridge passes the same check as a US one.
- Backups. cmd_backup waits until the save file has not changed for two seconds, then compares its SHA-256 hash with the newest backup and skips identical copies. Each new copy gets a timestamp and a tag such as pre, post or manual.
- Rotation. After each copy the script deletes the oldest files beyond the keep limit, 30 by default. That bounds disk use without hand cleaning.
- Restore. cmd_restore backs up the current save first with a pre-restore tag, then copies the chosen backup into place, so a restore never destroys the state you were restoring from.
- Launch. cmd_launch runs the checks, makes a pre-session backup, starts melonDS with the ROM path and waits. After the emulator exits it makes a post-session backup and appends the start time and length to sessions.csv.
The other commands cover recovery. Use list to see numbered backups and restore to roll back, with an optional filename to pick a specific one.
python hgss_companion.py backup
python hgss_companion.py list
python hgss_companion.py restore
python hgss_companion.py restore 20261027-201006-post.sav
On Windows, make a shortcut or a one-line batch file named play.bat with the launch command so you can start sessions with a double click. On macOS or Linux, make a small shell script or an alias. Either way, the script does the same work. If you sync folders to the cloud, sync the backups folder and leave the ROM and emulator folders alone.
To test your whole setup once, launch, load the game, save in the first town, exit the emulator normally, and check the backups folder. You should see a pre entry if a save already existed, plus a post entry from the session you just finished. If the post entry is missing, the emulator wrote its save somewhere else, and the troubleshooting section tells you how to find it.
Expected Output: What a Healthy HeartGold Run Looks Like
Compare your results with the examples below. Your numbers will differ, especially the ROM size, which depends on whether your dumper trimmed the file. The shape of the output should match.
Example output of the check command:
[ok ] emulator: C:\hgss-melonds\melonDS\melonDS.exe
[ok ] bios7 is 16384 bytes
[ok ] bios9 is 4096 bytes
[ok ] firmware is 262144 bytes
[ok ] ROM is Pokemon HeartGold (game code IPKE, title POKEMON HG)
[ok ] header checksum matches (527C)
[ok ] ROM size 128.0 MB
[ok ] save file: C:\hgss-melonds\roms\pokemon_heartgold.sav
Example output at the end of a session:
backed up to C:\hgss-melonds\backups\pokemon_heartgold\20261027-203015-pre.sav
backed up to C:\hgss-melonds\backups\pokemon_heartgold\20261027-213502-post.sav
session: 65.0 minutes
Example output of the list command after a week:
0 20261027-203015-pre.sav 524288 bytes
1 20261027-213502-post.sav 524288 bytes
2 20261028-190211-pre.sav 524288 bytes
3 20261028-201944-post.sav 524288 bytes
Two details matter in that output. First, the checksum line in the sample is a synthetic test value, so your real dump will show a different number. Second, a consistent save size across backups is a good health signal. If one backup is dramatically smaller, stop and investigate before you overwrite anything. The table below turns those observations into a checklist.
| Checkpoint | Healthy result | Warning sign |
|---|---|---|
| Validator run | Only ok lines, maybe one warn for a missing save | Any FAIL line, or an unexpected game code |
| First boot | Title screen with music within seconds | Black screen, freeze or error dialog |
| Touch screen | A click on the bottom screen taps the right spot | Taps land offset or only the top screen responds |
| First save | A .sav file appears beside the ROM | No file after saving in game |
| Backups folder | One pre and one post per session | Missing post entry, or backups of different sizes |
| Clock | In-game time matches your computer | Time stuck, jumping or frozen |
| Performance | Smooth map scrolling at your chosen scale | Stutter in battles or audio crackle |
Common Pitfalls With a PokÃĐmon HeartGold Emulator
Pitfall 1: Trusting save states as your only save. A state is tied to the emulator build, and a melonDS update or a switch to a fork can make old states unloadable. Always create real in-game saves and let the script back up the .sav file. Think of states as a convenience for tricky moments.
Pitfall 2: Using a fork by accident. Names like Project PM or WatermelonDS look close to melonDS in a search result, and the downloads page of a fork rarely says it is unofficial in large letters. Download from the official site, and check the About dialog after launching. A fork can ship different defaults, different save paths and different state formats.
Pitfall 3: Dumping a game once and never verifying it. A bad dump can run for hours before a crash at a specific map. Run the validator after every new dump. A header mismatch does not prove the dump is bad, but a wrong game code or a tiny file size does.
Pitfall 4: Changing the system clock to fast-forward events. It looks like a shortcut to a daily event, but it can leave the game’s stored time in an inconsistent state. Use a copy of the save for experiments, or wait for the real day.
Pitfall 5: Closing the emulator with the window button mid-save. Closing during a write risks a half-written save file. Wait for the in-game save confirmation, then close. The script’s two-second stability wait protects the backup copy, though it cannot protect the original file from a forced close.
Pitfall 6: Putting the project inside a cloud-sync folder. Sync clients lock files and may revert a newer save to an older cloud version after a conflict. Keep the live folder local and sync only the backups directory, so the cloud never touches a file the emulator is writing.
Pitfall 7: Ignoring the touch screen mapping. Players who build a perfect keyboard layout and forget the mouse find the PokÃĐgear unusable. Test a touch action, such as opening the PokÃĐgear map, before you start a long session. Runs that rely on hard rules, such as a Nuzlocke challenge on an emulator, depend on reliable saves, so fix input and saves first.
Troubleshooting: 10 Problems and Their Fixes
Start with the validator. Most problems show up there before the emulator opens. If the issue persists, work through the matching group below. For wider context on how this site organizes emulator guides, the gaming section lists related tutorials.
Boot and file errors
- The validator says the emulator is missing. The path in hgss.json does not match your folder. On macOS the executable sits inside the app bundle, and on Windows it is melonDS.exe inside the extracted folder. Fix the melonds key and run check again.
- FAIL: bios7 or bios9 has the wrong size. The file is a bad dump or the wrong file renamed. The ARM7 BIOS must be 16,384 bytes and the ARM9 BIOS must be 4,096 bytes. Re-dump from your console instead of trying to repair the file.
- FAIL: game code is not HeartGold or SoulSilver. You pointed the config at a different game or an unusual dump. Read the code the script prints and compare it with the label on your cartridge. If they match but the script still fails, the file may be corrupt or from a modified release.
- The game boots to a black screen. Switch between direct boot and firmware boot, then confirm the BIOS paths. If the problem remains, turn off the JIT recompiler to rule out a compatibility issue with your CPU or operating system build.
Performance and display
- Slow or choppy emulation. Lower the 3D resolution to native, confirm the JIT recompiler is on, and close background apps. Integrated graphics struggle at higher scales, so step down before blaming the emulator.
- Audio crackles or stutters. Raise the audio latency slightly and make sure VSync is on. If it persists, check that your operating system is not switching the output device sample rate mid-session.
- The touch screen taps the wrong spot. Your screen layout or window scaling is offset. Reset the layout to default, restart, and test again. Avoid overlay software that moves or scales the emulator window after launch.
Saves and clock
- No .sav file appears. Either you never saved in game, or the emulator writes saves to a custom folder. Check the save path in the emulator settings, then point the script’s rom key to the same location or move the save next to the ROM.
- The post-session backup is missing. The script skips a backup when the save is identical to the last one, so no new file can mean no progress. If you did play and save, confirm the emulator exited normally rather than crashing.
- The in-game clock looks wrong. melonDS follows your computer clock, so check your system time zone and daylight saving setting first. Fix the system clock, restart the emulator, and avoid changing it again during a run.
Those cover the failures reported most often. If you hit something not listed, copy the exact validator output, because a wrong file size or game code solves more mysteries than any amount of guessing.
Advanced Tips for Long HeartGold and SoulSilver Runs
Single-screen play. Community projects exist to patch HeartGold and SoulSilver for a one-screen experience. One of them, called 1ScreenHGSS, reportedly documents patching a legally obtained ROM and then choosing the top-only screen option in melonDS. Patching changes the file, so the validator’s header and game-code checks may react, and you should keep an untouched dump beside any patched copy. Treat patches as an advanced step after the vanilla setup works.
Native recompilation projects. The Recompendium catalog of DS games on PC lists a SoulSilver project, ssrecomp, that statically recompiles the game code and uses the melonDS core in place of DS hardware, plus an active decompilation effort called pokeheartgold. The catalog describes the SoulSilver build as designed for single-screen play and requiring your own copy of the game. The catalog lists version 0.1.3 and this is not an official PokÃĐmon or Nintendo release, so expect rough edges. Browse the Recompendium DS catalog to follow progress.
Phone play. melonDS Android reportedly reached version 2.0.1 on May 5, 2026, after 2.0.0 on April 18. The same ROM works there, but the settings and touch handling differ, so run the validator on your PC first and copy the validated files to your phone. Treat the phone save as a separate copy unless you manage syncing yourself.
Companion apps. A community app called PokeDaisy reportedly offers party, bag, map and guide features for SoulSilver on Android, with battle support unavailable. It is a single-source report, so check its repository before relying on it. It is a handy second-screen tool, not a replacement for the emulator.
Scripting your own checks. The companion script is deliberately small. Extend it with a hash of your ROM stored in hgss.json to catch silent file corruption, or add a notification when no backup has been made for a week. If you compare WatermelonDS or other forks before switching, run a full save backup first and test the fork on a copy of your save.
Future-proofing. If melonDS 1.2 arrives, install it into a separate folder, copy your .sav file over, and keep the 1.1 folder until you have played an hour on the new build. Do not carry save states across versions. This is the same migration pattern we use for any emulator update, and it costs ten minutes.
Frequently Asked Questions
Which PokÃĐmon HeartGold emulator is best, and does it run SoulSilver too?
For desktop play, official melonDS 1.1 is the best choice for both games, and a PokÃĐmon SoulSilver emulator setup is identical apart from the ROM file. It has the JIT recompiler, OpenGL upscaling, a working clock and savestates, and it is actively maintained. On phones, melonDS Android is the matching option.
Is melonDS free?
Yes. The official melonDS desktop emulator is free and open source under the GPL-3.0 license, and no paid plan or subscription exists for it. Be cautious with any site that asks for payment to download it.
Do I need BIOS and firmware files?
Community setup notes recommend dumping them from your own DS, and the validator in this guide warns when they are missing. For the most accurate behavior, provide them. Check the melonDS Howto and FAQ page for what the current build supports without them.
Can I download the ROM instead of dumping my cartridge?
We do not recommend or link to ROM downloads. Dumping a cartridge you own is the safe and supported route in this guide, and it also guarantees a clean file that passes the header checks.
Does the PokÃĐwalker work in an emulator?
No. The PokÃĐwalker was a separate pedometer device that linked by infrared, so its features need hardware that an emulator does not provide. The main story and post-game still play normally.
Is there a newer melonDS than 1.1?
Not as an official standalone desktop release as of October 27, 2026. The project plans a 1.2 release without a published date. Forks such as WatermelonDS and Project PM have newer-looking version numbers, but they are separate projects.
Can I move my save from a real cartridge or another emulator?
Yes, in principle. Dump the cartridge save with your dumper, rename it to match your ROM, and place it beside the ROM. Back up the file first and run the validator and a test launch before you play on it. Saves from other emulators may need conversion, so keep the original copy.
Will this guide work for both HeartGold and SoulSilver?
Yes. The validator accepts both games and every region code in its table. Set the rom key in hgss.json to the file you want to run, and use a separate project folder for each version if you plan to play both.





