/// FIELD NOTES FROM A SELF-AWARE GAME SITE
RetroArch Cores 2026: Install & Tune, 14 Steps, 30 Min
There is a specific kind of disappointment that arrives the first time you open RetroArch. You installed the thing, you launched it, you were promised a universal emulator that runs everything from Pong to the PlayStation, and you are now staring at a menu that does precisely nothing. No consoles. No games. Just a horizontal ribbon of icons and a stubborn refusal to run a single ROM. This is not a bug. This is the entire design philosophy of RetroArch, expressed as an empty room.
RetroArch does not emulate anything. It is a frontend, a shell, a runtime, and every ounce of actual emulation happens inside a core. No cores, no games. The whole skill of running RetroArch well is the skill of choosing, installing, and configuring cores, and almost every tutorial you will find skips straight to a copy-pasted list of core names without ever explaining what a core is, why there are five of them for the SNES, or why your PlayStation discs boot to a black screen while your NES ROMs run fine. This guide fixes that. As of this writing the current stable build is RetroArch 1.22.2, released in November 2025 under the GPLv3, and everything below is written and tested against it. Budget about thirty minutes for a clean setup, most of which is spent staging BIOS files and waiting on downloads.
What a Core Actually Is
Before you install anything, understand the machine you are operating. Ninety percent of RetroArch confusion is a mental model problem: people think RetroArch is an emulator with a lot of settings. It is not. It is a host for many separate emulators, and every one of your problems will make more sense once you internalize that.
The libretro API in one paragraph
libretro is a thin, stable C interface that sits between a frontend and an emulator. The frontend, RetroArch being the reference implementation, knows how to draw video, play audio, read controllers, manage save files, and paint a menu. It knows absolutely nothing about how a Super Nintendo works. A core is a shared library, a .dll on Windows, a .so on Linux, a .dylib on macOS, that implements the libretro API and does know how a Super Nintendo works. The frontend hands the core input and a slice of memory to draw into; the core hands back pixels and sound. That contract is the whole trick. Because the contract is versioned and stable, one frontend can run hundreds of cores, and one core can run under any libretro frontend. RetroArch is not the only one: Lakka, Batocera, and RetroPie all embed the same libretro cores behind different skins. If you would rather have the frontend handled for you on a dedicated box, our Batocera 4.3.1 install walkthrough covers the distro route, and it is running the exact cores described here. The canonical documentation lives at the libretro docs site.
A core is not an emulator (it is an emulator wearing a uniform)
Most cores are existing, famous emulators that someone ported to libretro. Snes9x, mGBA, Genesis Plus GX, Mupen64Plus, Stella, and PPSSPP all have a standalone life and a libretro incarnation. The libretro version is not a lesser copy or a stripped-down clone; it is the same emulation code with the platform-specific input, video, and audio plumbing torn out and replaced by libretro calls. When you hear that a core is 'accurate,' that accuracy belongs to the upstream emulator, not to RetroArch. RetroArch just gives it a window, a gamepad, and a save folder.
Not every core is even an emulator. ScummVM runs classic point-and-click adventures. NXEngine runs the freeware Cave Story. TIC-80 and Lutro are fantasy-console runtimes. There is an FFmpeg core that plays video files, and there is a core that is literally the game 2048. So the phrase 'RetroArch is an emulator' is doubly wrong: RetroArch is not an emulator, and cores are not always emulators. RetroArch is a runtime, and cores are the programs it runs.
How cores are named, and why it matters
Every core file carries the _libretro suffix: snes9x_libretro.so, mupen64plus_next_libretro.dll, mednafen_psx_hw_libretro.dylib. Sitting next to each core is a matching info file, snes9x_libretro.info, that tells RetroArch four things: the human-readable name to show in the menu, the systems the core emulates, the file extensions it accepts, and any BIOS or firmware it requires. If those info files are missing or stale, cores show up under cryptic filenames, BIOS detection silently breaks, and the content scanner cannot associate your ROMs with the right core. This is why 'Update Core Info Files' is step zero of every manual install, and why a fresh copy of the entire info set lives in the libretro-core-info repository. Cores are the engine; info files are the registration papers. Drive without them and you will get pulled over.
Prerequisites: Versions, Hardware, BIOS
Three things determine whether your setup works: the versions you install, the hardware you install them on, and the BIOS files you stage beforehand. Get these three right and the rest is mechanical.
Software versions
Install RetroArch 1.22.2 (November 2025) or newer from an official source only: the official GitHub releases, the retroarch.com download page, the libretro buildbot, your platform's app store, or Steam. Avoid the 'all-in-one' bundles that flood search results; they ship stale binaries, sometimes months out of date, and occasionally arrive pre-loaded with ROMs of extremely questionable provenance. The Android build tracks the same version line (1.22.2 at time of writing), and the desktop builds are identical in behavior across Windows, Linux, and macOS.
The single most important versioning rule in this entire guide: your cores and your frontend must come from the same lineage. The libretro API is versioned, and a core built against a newer API than your frontend will refuse to load with the maddeningly vague message 'Failed to open libretro core.' If you install RetroArch from the buildbot, install cores from the buildbot. If you install from Steam, use Steam's core downloader. Do not marry a two-year-old distro-packaged RetroArch to today's nightly cores and then wonder why nothing loads. When in doubt, update both sides together.
Hardware requirements by system tier
There is no single spec sheet for RetroArch because a core for the Game Boy and a core for the Sega Saturn live in different universes of difficulty. Think in tiers. Tier 1 runs on a potato: NES, SNES, Game Boy / Color / Advance, Genesis and Master System, PC Engine, Neo Geo Pocket, WonderSwan, and the Atari machines will run full speed on literally any device made in the last decade, including sub-$100 handhelds. Budget handhelds such as the Miyoo Mini Plus run a RetroArch-based OS (OnionOS) and lean entirely on this tier. Tier 2 is modest: Nintendo 64, PlayStation, 2D Saturn, and arcade up through CPS-3 want a Raspberry Pi 4 or 5, a mid-range phone, or any laptop from the last several years. Tier 3 needs real silicon: 3D Saturn, PSP, Nintendo DS, and upscaled PlayStation at 4x or higher with PGXP enabled will punish weak chips. This is where a strong ARM handheld earns its keep; we broke down that performance gap in the Retroid Pocket 6 vs 5 comparison. Tier 4 you mostly should not attempt in RetroArch at all: PlayStation 2 and GameCube / Wii. Cores exist, but they trail their standalone counterparts so badly that recommending them would be malpractice.
For RAM, 2GB is the floor, 4GB is comfortable, and 8GB matters only if you plan to run run-ahead in second-instance mode with heavy shaders, which spins up a second copy of the core in memory. Cores themselves are tiny, a few megabytes each; it is your content and thumbnails that eat storage. On a Raspberry Pi the calculus shifts again, and it is worth reading why RetroPie has been frozen at v4.8 before you commit to that platform.
BIOS and system files (stage these first)
Several systems will not run without a BIOS: PlayStation, Saturn, Sega CD, Nintendo DS, PC Engine CD, and Neo Geo, plus optional-but-recommended firmware for the Game Boy Advance. RetroArch looks for these in a single system directory. Stage them before you scan content so that step seven of the walkthrough is a formality rather than an afternoon of debugging black screens. The exact filenames matter down to the letter and the case, and we tabulate them later. Legally, the clean path is to dump BIOS and games from hardware you own; the same principle applies to cartridges, which you can rip yourself as shown in our Retrode cartridge-dumping guide. RetroArch can verify BIOS files against known hashes, so there is no excuse for guessing.
Choosing the Right Core Per System
The reason there are multiple cores per console is not indecision. It is a genuine engineering trade-off, and once you see the axis, every 'which core should I use' argument in every forum thread collapses into the same two-line answer.
Accuracy vs performance: the only axis that matters
Cycle-accurate cores reproduce the original hardware's quirks: exact timing, mid-scanline effects, correct audio DSP behavior, and the specific bugs that games were coded around. bsnes, the Mednafen-derived Beetle family, and Mesen live at this end. They cost CPU, sometimes a lot of it. Performance cores cut corners you will almost never notice during actual play, in exchange for running full speed on weak chips. Snes9x, PCSX ReARMed, gpSP, PicoDrive, and QuickNES live at this end. On a desktop with cycles to burn, default to accuracy. On a handheld or a Pi, default to performance. There is no universally best core; there is only the best core for your silicon and your game. Anyone who tells you otherwise is selling a preference as a fact.
The recommended cores, system by system
The table below is the shortlist. The accuracy pick assumes you have the hardware; the performance pick is the fallback for weaker devices. When the two columns name the same thing, that core is simply the consensus answer.
| System | Accuracy pick | Performance / low-end pick |
|---|---|---|
| NES | Mesen | FCEUmm / QuickNES |
| SNES | bsnes | Snes9x (Snes9x 2010 on very weak chips) |
| Game Boy / Color | SameBoy | Gambatte |
| Game Boy Advance | mGBA | gpSP |
| Genesis / CD / 32X | Genesis Plus GX | PicoDrive |
| Nintendo 64 | Mupen64Plus-Next | ParaLLEl N64 (see 2025 note) |
| PlayStation | Beetle PSX HW | PCSX ReARMed |
| PSP | PPSSPP | PPSSPP (lower resolution) |
| Sega Saturn | Beetle Saturn | YabaSanshiro / Kronos |
| PC Engine / TG-16 | Beetle PCE | Beetle PCE Fast |
| Arcade | FBNeo / current MAME | MAME 2003-Plus |
| Nintendo DS | melonDS | DeSmuME |
| Atari 2600 | Stella | Stella |
| DOS | DOSBox-Pure | DOSBox-Pure |
Systems where the answer is 'use a standalone emulator'
Be honest about RetroArch's range. Its strength is the 8-, 16-, and 32-bit eras plus arcade, and there it is unbeatable. For sixth-generation 3D and beyond, standalone emulators lead by a wide margin. PlayStation 2 support in libretro (the experimental LRPS2 line) is not something you should rely on; use standalone PCSX2. The Dolphin core for GameCube and Wii has been neglected for years and trails standalone Dolphin badly. There is no libretro core for the Nintendo 3DS or the Switch at all; those live entirely in standalone emulators. You can still launch a standalone emulator from within RetroArch's menu using a launcher-style core or a playlist entry, but the emulation itself happens outside libretro. Pretending a weak PS2 core is 'good enough' is how people end up with a library of games that stutter; pick the right tool.
Install & Load Cores: 14 Steps
This is the spine of the guide. Fourteen steps take you from a blank install to a tuned, verified, backed-up setup. Each step includes the reason it exists, because a step you understand is a step you can debug.
Steps 1-5: Get RetroArch and your first core
- Install RetroArch from an official source. Rationale: official builds keep the frontend and the Online Updater on the same version channel, which is the whole ballgame for core compatibility. Third-party bundles ship stale binaries and sometimes worse.
- Launch it once, then quit. Rationale: the first launch writes
retroarch.cfgand creates the directory skeleton. You cannot sanely configure folders that do not exist yet. After this step your install looks like the tree below, which doubles as your first expected-output check.
~/.config/retroarch/ # Linux; Windows portable uses the RetroArch\ folder
├── retroarch.cfg # main config
├── cores/ # .so / .dll / .dylib core files live here
│ ├── snes9x_libretro.so
│ ├── mupen64plus_next_libretro.so
│ └── mednafen_psx_hw_libretro.so
├── info/ # <corename>_libretro.info metadata (names, BIOS, extensions)
├── system/ # BIOS files go here (scph5501.bin, bios7.bin, ...)
├── config/ # per-core and per-game override .cfg / .opt files
│ └── Beetle PSX HW/
│ ├── Beetle PSX HW.cfg # core override
│ └── Final Fantasy VII (USA).cfg # per-game override
├── saves/ # battery saves (.srm) and memory cards
├── states/ # save states (.state)
├── playlists/ # your scanned game lists (.lpl)
└── thumbnails/ # boxart, snaps, titles- Run Online Updater and update the metadata first. Do 'Update Core Info Files,' then 'Update Assets,' then 'Update Databases.' Rationale: info files turn a raw library into a named, BIOS-aware, scannable core; assets draw the menu; databases power the content scanner. Doing this before you download cores means every core you pull arrives fully labeled.
- Open Online Updater then Core Downloader and install one core for a system you actually own games for, say Snes9x. Rationale: prove the pipeline works with a single known-good core before you download forty and have no idea which one is misbehaving.
- Alternatively, install a core by hand from the buildbot. Rationale: some platforms, locked-down consoles and certain Linux packages, ship without the in-app updater. The buildbot is the exact same source the updater pulls from, so the result is identical. The official install-cores guide documents both routes.
# Linux x86_64 - pull a single core straight from the nightly buildbot
cd ~/.config/retroarch/cores
# Beetle PSX HW (hardware-renderer PlayStation core)
wget https://buildbot.libretro.com/nightly/linux/x86_64/latest/mednafen_psx_hw_libretro.so.zip
unzip mednafen_psx_hw_libretro.so.zip
rm mednafen_psx_hw_libretro.so.zip
# Windows path is analogous:
# https://buildbot.libretro.com/nightly/windows/x86_64/latest/mednafen_psx_hw_libretro.dll.zip
# macOS (Apple Silicon):
# https://buildbot.libretro.com/nightly/apple/osx/arm64/latest/mednafen_psx_hw_libretro.dylib.zip
# After copying cores in by hand, open RetroArch and run:
# Online Updater -> Update Core Info Files
# so the frontend knows each core's name, extensions, and required BIOS.On a Debian or Ubuntu system you can skip the manual dance and pull cores as packages from the libretro PPA, which is the tidiest route when it is available:
# Debian / Ubuntu via the libretro PPA
sudo add-apt-repository ppa:libretro/stable
sudo apt-get update
sudo apt-get install retroarch libretro-snes9x libretro-mgba libretro-genesisplusgx
# Individual cores follow the pattern: libretro-<corename>
# List everything available:
apt-cache search libretro-Steps 6-10: BIOS, content, and running a game
- Stage your BIOS files in the
systemdirectory using exact filenames. Rationale: PlayStation, Saturn, Sega CD, DS, and Neo Geo cores boot to a black screen without correctly named BIOS. Get this right once and never think about it again. Filenames and the BIOS table come in the next section. - Point RetroArch at your content and scan it: Import Content then Scan Directory. Rationale: the scanner hashes each ROM against the database and builds per-system playlists that auto-associate the correct core, so you are not picking a core by hand every single time.
- Load a game from a playlist. Rationale: playlists remember the default core per system. The first time you launch a system, RetroArch asks which core to use and then remembers your answer for that whole list.
- If a game refuses to scan (arcade sets, homebrew, unusual extensions), load it manually: Load Content, pick the file, pick the core. Rationale: the database cannot know every dump in existence; manual load bypasses the scanner entirely.
- Verify the load in the log. Rationale: the log states the core version, whether BIOS was found and hash-matched, which renderer is active, and precisely why a load failed. A healthy PlayStation launch looks like the output below.
[INFO] [Core]: Loading dynamic library: mednafen_psx_hw_libretro.so
[INFO] [Core]: Version of libretro API: 1, Compiled against API: 1
[INFO] [Environ]: SET_PIXEL_FORMAT: RGB565.
[INFO] [Content]: Loading content file: Final Fantasy VII (USA) (Disc 1).chd
[INFO] [Beetle PSX]: BIOS file "scph5501.bin" found. MD5: 490f666e...
[INFO] [Beetle PSX]: Using hardware renderer (Vulkan).
[INFO] [Core]: Content ran for 1 frame(s).
[INFO] [Playlist]: Written to "Sony - PlayStation.lpl".Steps 11-14: Options, overrides, verification, maintenance
- Set core options: Quick Menu then Core Options. Rationale: this is where internal resolution, region, renderer, and accuracy hacks live, and the defaults are deliberately conservative so the core boots on anything.
- Save your settings as an override, never to the global config: Quick Menu, Overrides, Save Core Overrides or Save Game Overrides. Rationale: overrides keep per-core and per-game tweaks isolated so one core's needs never corrupt another's, and so a bad experiment is one file deletion away from undone.
- Update installed cores deliberately: Online Updater then Update Installed Cores. Rationale: updates fix bugs and add features, but they occasionally introduce regressions. On a working setup, update on purpose, not reflexively, and read the next point before you trust a fresh N64 core.
- Back up
retroarch.cfg, theconfig/folder, andsaves/. Rationale: overrides and battery saves represent hours of tuning and play, they are small, and they are trivially easy to lose to a bad update or a reinstall. The one-line backup command is in the final section.
Core Options & Per-Game Overrides
The override system is RetroArch's single best feature and its single most misunderstood one. Learn it and you stop fighting your config; ignore it and you will spend years wondering why fixing your PlayStation settings quietly broke your NES.
Where core options live
Core options are the settings specific to a core: internal resolution, renderer, region, and the pile of accuracy and enhancement toggles. Modern RetroArch, with game_specific_options enabled, writes these to a per-core .opt file under config/<Core Name>/. That file holds only that core's options and nothing else. You almost never hand-edit it; you set values in Quick Menu, Core Options, and RetroArch writes the file for you. What it writes looks like this, and it is worth seeing so you know what you are backing up:
# config/Beetle PSX HW/Beetle PSX HW.opt
# Core OPTIONS (note the .opt extension) - written when you
# set these in Quick Menu -> Core Options and hit save.
beetle_psx_hw_renderer = "hardware"
beetle_psx_hw_internal_resolution = "2x"
beetle_psx_hw_pgxp_mode = "memory only"
beetle_psx_hw_pgxp_texture = "enabled"
beetle_psx_hw_dither_mode = "internal resolution"
beetle_psx_hw_widescreen_hack = "disabled"
beetle_psx_hw_skip_bios = "disabled"The override hierarchy: core, content-dir, game
RetroArch layers configuration from least to most specific, and the most specific wins. The order is: global retroarch.cfg, then a core override (config/<Core>/<Core>.cfg), then a content-directory override, then a per-game override (config/<Core>/<Game>.cfg). Input remaps ride alongside as .rmp files, and core options layer at both core and game scope through those .opt files. The rule of thumb writes itself: put display driver and truly global choices in the global config; put 'this core always wants X' in a core override; put 'this one game needs a specific shader, aspect ratio, or run-ahead value' in a game override. A per-game override file is small and surgical:
# config/Beetle PSX HW/Final Fantasy VII (USA).cfg
# A PER-GAME override - loaded only when this exact content runs.
# Create it via: Quick Menu -> Overrides -> Save Game Overrides
video_aspect_ratio_auto = "false"
aspect_ratio_index = "22" # 22 = core-provided aspect
video_shader_enable = "true"
video_shader = "~/.config/retroarch/shaders/crt/crt-guest-advanced.slangp"
run_ahead_enabled = "true"
run_ahead_frames = "1"A worked example: Beetle PSX HW
Here is the whole system in one motion. Open a PlayStation game, go to Core Options, set the renderer to hardware, internal resolution to 2x, PGXP operation mode to 'memory only,' and turn on PGXP perspective-correct texturing. Those four settings are the ones the Beetle PSX HW documentation recommends as the sweet spot: sharper 3D and stable geometry without the compatibility landmines of the more aggressive 'memory + CPU' mode. Save that as a Core Override so every PlayStation game inherits it. Then, when you hit the occasional title whose graphics break with PGXP on, and a few do, open that specific game, turn PGXP off, and save a Game Override. Now the exception is scoped to the one game that needs it and your global default stays clean. That is the entire philosophy: sensible defaults at the core level, surgical exceptions at the game level, and a global config you almost never touch.
BIOS and System Files Done Right
More first-time failures trace to BIOS than to any other cause. The fix is boring precision: the right file, the right name, the right folder. Do it once, correctly, and you will never see a mystery black screen again.
The system directory and how cores find BIOS
RetroArch exposes a single system_directory setting, and cores look there by default; a few look in per-system subfolders, which the docs for each core spell out. Crucially, RetroArch can tell you what a core wants and whether it has it: load the core with no content, open Information, then Core Information, and you get a firmware list showing each required and optional file, plus whether it is present and hash-matched. Stage BIOS before you scan content and this screen will be a wall of green rather than a diagnosis.
The filenames that actually matter
Case and spelling are load-bearing, especially on Linux, where the filesystem is case-sensitive and SCPH5501.bin is a different file from scph5501.bin. The essentials:
| System | Core | Required BIOS filename(s) |
|---|---|---|
| PlayStation | Beetle PSX HW | scph5500.bin (JP), scph5501.bin (US), scph5502.bin (EU); OpenBIOS fallback if none present |
| Sega Saturn | Beetle Saturn / Kronos | sega_101.bin (JP), mpr-17933.bin (US/EU) |
| Sega CD | Genesis Plus GX | bios_CD_U.bin, bios_CD_E.bin, bios_CD_J.bin |
| Nintendo DS | melonDS | bios7.bin, bios9.bin, firmware.bin |
| Game Boy Advance | mGBA | gba_bios.bin (optional; improves boot and compatibility) |
| PC Engine CD | Beetle PCE | syscard3.pce |
| Neo Geo | FBNeo | neogeo.zip (in system/ or with the romset) |
| PSP | PPSSPP | none required (high-level BIOS) |
The PlayStation names in particular are worth memorizing because they trip up everyone: scph5501.bin is the US BIOS, and if you drop in a Japanese scph5500.bin and try to run a US game, some titles complain. Beetle PSX HW ships an OpenBIOS fallback so it will boot without any BIOS at all, but real BIOS gives you the correct boot sequence and the best compatibility, so supply your own.
Verifying BIOS with the built-in checker
Never assume. Load the core, open Core Information, and read the firmware status. Alternatively, watch the log on content load: a line reading BIOS file "scph5501.bin" found. MD5: ... is your green light, and 'firmware missing' or 'not found' means your filename, casing, region, or folder is wrong. The legal route to these files, as with the games themselves, is to dump them from hardware you own; if you are already dumping cartridges with a Retrode-style setup, you are most of the way to a fully legitimate library.
Six Common Pitfalls (and Fixes)
These are the mistakes that generate the most forum threads. Every one of them is preventable, and every one of them has a one-line fix once you know the cause.
Pitfalls 1-3: install and version mistakes
Pitfall 1 — wrong architecture. Symptom: 'Failed to open libretro core.' Cause: a 32-bit core on a 64-bit build, an x86 core on an ARM device, or simply the wrong operating system's binary. Fix: download the core from the buildbot path that matches your operating system and CPU architecture exactly, and never mix them.
Pitfall 2 — mixing frontend and core versions. Symptom: cores that used to load stop loading after you update one side. Cause: the libretro API version drifted between your frontend and your cores. Fix: update both from the same channel; whenever you bump the frontend, immediately run Update Installed Cores so the whole set moves together.
Pitfall 3 — chasing accuracy on weak hardware. Symptom: buttery smooth on your desktop, a slideshow on your handheld. Cause: bsnes, Beetle Saturn, and 4x PGXP are genuinely heavy. Fix: run Snes9x, PCSX ReARMed, and native resolution on ARM devices, and reserve the cycle-accurate cores for x86 machines that can actually feed them.
Pitfalls 4-6: BIOS, config, and content
Pitfall 4 — BIOS name, casing, or region. Symptom: black screen, or 'firmware missing.' Cause: the exact filename is wrong. Fix: match the filename precisely, in the correct case, for the correct region, in the correct folder, then confirm it in Core Information before blaming the core.
Pitfall 5 — editing the global config for one core's benefit. Symptom: fixing PlayStation quietly breaks NES; settings seem to change on their own. Cause: everything is being saved to the global config. Fix: use core and game overrides, and keep the global config generic and boring. Your future self will thank you.
Pitfall 6 — renaming ROMs or refusing to use CHD. Symptom: lost battery saves, multi-disc games that will not swap discs, and CD images that eat your storage. Cause: saves are keyed to the content filename, and loose BIN/CUE sets are large and awkward. Fix: never rename a ROM after you have created a save for it, convert CD content to CHD, and use an M3U playlist to bundle multi-disc games so disc swapping and shared memory cards just work.
Troubleshooting Table
When something breaks, resist the urge to start randomly toggling settings. Do the one disciplined thing first, then consult the table.
Read the log first
Always. Go to Settings, Logging, and set both frontend and core logging to at least Info level, then reproduce the failure and read the first ten lines. The overwhelming majority of 'it just does not work' reports are answered explicitly in the log: a missing BIOS, an architecture mismatch, a renderer that failed to initialize, a content file the core does not recognize. The log is not decoration; it is the diagnosis.
The table
| Symptom | Likely cause | Fix |
|---|---|---|
| No cores in the list; nothing loads | Fresh install, no cores downloaded | Online Updater, Core Downloader; or copy cores into cores/ then run Update Core Info Files |
| 'Failed to open libretro core' | Architecture or OS mismatch | Redownload the core from the buildbot path matching your exact OS and CPU |
| Black screen on PS1 / Saturn / Neo Geo | Missing or wrong-named BIOS | Place the exact BIOS filename in system/; verify in Core Information |
| Audio crackles or game runs too fast/slow | Audio sync off or wrong refresh rate | Enable audio_sync, set the correct display refresh, try audio_latency 64-96 |
| N64 game will not load or crashes (2025 builds) | mupen64plus-next regression from early 2025 | Switch to ParaLLEl N64, or roll back to a January 2025 core build from the buildbot archive |
| Playlist scan finds nothing | Wrong extensions or arcade set mismatch | Check the core's supported extensions; match the arcade romset to that core's MAME/FBNeo version |
| Save states work but battery saves vanish | Wrong savefile_directory or renamed ROM | Set savefile_directory; never rename ROMs after saving; back up saves/ |
| Fast-forward or run-ahead does nothing | Core lacks save-state support, or run-ahead is off | Enable run-ahead under Latency; use second-instance mode for stateless cores |
| Vulkan cores crash but GL cores work (or vice versa) | Driver / renderer mismatch | Switch video_driver between vulkan and glcore per core; update GPU drivers |
| Overrides refuse to save | rgui_config_directory unset or read-only | Set rgui_config_directory and ensure the folder is writable |
| Thumbnails and boxart missing | Playlist names do not match the thumbnail server | Rebuild the playlist via the scanner, then run Update Thumbnails |
| Arcade ROM 'not found' though the zip is present | Romset version mismatch (parent/clone/BIOS) | Match the romset to the core's MAME/FBNeo revision; keep neogeo.zip in system/ |
The 2025 N64 situation specifically
It earns its own heading because it caught a lot of people off guard. Community reports on the libretro forums flagged 2025 as a rough year for Nintendo 64 emulation in RetroArch: a regression introduced early in the year in mupen64plus-next broke certain titles outright, with users specifically reporting that Stunt Racer 64 and World Driver Championship stopped loading, and many simply reverted to the last known-good build from January and stayed there. If N64 games misbehave in a 2026 build, you have three options. First, switch to ParaLLEl N64, which uses a different RSP and RDP path and sidesteps the regression entirely. Second, stay on mupen64plus-next but change its graphics plugin from the default GLideN64 to ParaLLEl-RDP or Angrylion, since the fault is path-specific. Third, roll back to a dated January 2025 core build from the buildbot's archive. The official Mupen64Plus core docs and the mupen64plus-libretro-nx repository track the state of play; check them before you assume your setup is at fault, because in this case it very likely is not.
Advanced: Run-Ahead, Shaders, Netplay
Once the basics run, RetroArch has a layer of features that no standalone emulator matches. These are what turn a working setup into a genuinely better-than-original experience.
Run-ahead: killing input lag
Real hardware had input latency; so does emulation, and it stacks. Run-ahead attacks the game's own internal lag by computing future frames in the background and rolling the display forward to the earliest frame that reflects your input, which is a completely separate mechanism from GPU hard-sync or frame delay. Configure it under Quick Menu or Settings, then Latency. To find the right frame count for a game, the run-ahead documentation gives a precise method: pause emulation, hold a direction on the pad, and frame-advance until the character moves; the lag is the number of advances minus one. Start at a single frame, which is enough for most games, and only raise it if control still feels mushy. There are two modes. Single-instance is cheaper but disables audio and video while it computes the hidden frames. Second-instance runs a second copy of the core to calculate ahead, syncing only when input changes; it is safer and works with cores whose fast-forward misbehaves, at the cost of more CPU and RAM. Run-ahead needs functioning save states, so second-instance mode is also the workaround when a core lacks them.
# Latency - run-ahead (Settings -> Latency, or per game via overrides)
run_ahead_enabled = "true"
run_ahead_frames = "1" # start at 1; raise until control feels instant
run_ahead_secondary_instance = "true" # safer: a 2nd core copy handles the hidden frames
run_ahead_hide_warnings = "false"
# Related low-latency knobs
video_hard_sync = "true" # GL / GLcore only; forces CPU/GPU sync
video_hard_sync_frames = "0"
video_max_swapchain_images = "2" # Vulkan / D3D; 2 = lower latency, 3 = smootherShaders and the aesthetics of accuracy
These games were drawn for CRTs, and on a flat modern panel their art looks wrong: dithering that was meant to blend into a soft phosphor glow instead reads as raw checkerboard noise. CRT shaders such as crt-guest-advanced, crt-royale, and the Lottes preset simulate scanlines, shadow masks, and bloom to put that intent back. The modern slang shaders require the vulkan or glcore video driver. For handheld systems there are LCD-grid and dot-matrix shaders that recreate the Game Boy's pixel grid. Presets stack and are saved as .slangp files, and you assign them per core or per game through the same override system covered earlier, so your PlayStation can wear a CRT mask while your Game Boy Advance wears an LCD grid. The cost is real: shaders are GPU-bound, and a heavy CRT preset at 4K can cost more performance than the emulation itself. Turn off bilinear smoothing (video_smooth = false) and let the shader do the filtering, because layering the two just produces mud.
Netplay, softpatching, and achievements
Netplay lets two people play the same core in lockstep over the network; both sides need an identical core and a matching content hash, and you connect through the built-in lobby. Softpatching is quietly one of RetroArch's best tricks: drop a matching .ips, .bps, or .ups patch next to your ROM and RetroArch applies it in memory at load time without ever modifying the original file, which is how fan translations and romhacks run without you maintaining a second copy of the game. RetroAchievements, enabled with cheevos_enable, adds an achievement layer to supported cores; its hardcore mode disables save states, rewind, and cheats to keep the playing field level. And remember that some cores are contentless: 2048, ScummVM, and DOSBox-Pure can start with no ROM at all. For CD-based systems, convert your discs to CHD with chdman first; it shrinks the files substantially and cores read it faster than loose BIN/CUE.
A Complete Working retroarch.cfg
Everything above condenses into one config file. This is a sane, portable baseline for RetroArch 1.22.2 that you can drop in and adjust. It is deliberately opinionated: Vulkan by default, run-ahead off globally so you enable it per game, and overrides doing the heavy lifting so this file stays generic.
The annotated config
# =====================================================================
# retroarch.cfg - a sane, portable baseline (RetroArch 1.22.2)
# Linux paths shown; adjust ~/.config/retroarch for your OS.
# =====================================================================
# ---- Directories ----------------------------------------------------
libretro_directory = "~/.config/retroarch/cores"
libretro_info_path = "~/.config/retroarch/info"
system_directory = "~/.config/retroarch/system"
savefile_directory = "~/.config/retroarch/saves"
savestate_directory = "~/.config/retroarch/states"
rgui_config_directory = "~/.config/retroarch/config"
playlist_directory = "~/.config/retroarch/playlists"
video_shader_dir = "~/.config/retroarch/shaders"
# ---- Core updater (keep frontend + cores on one channel) ------------
core_updater_buildbot_cores_url = "http://buildbot.libretro.com/nightly"
core_updater_auto_extract_archive = "true"
core_updater_show_experimental_cores = "false"
# ---- Video ----------------------------------------------------------
video_driver = "vulkan" # try "glcore" if a core misbehaves
video_fullscreen = "true"
video_vsync = "true"
video_scale_integer = "false"
video_smooth = "false" # off = crisp pixels; let shaders filter
video_shader_enable = "false" # flip on per core/game via overrides
video_max_swapchain_images = "2"
# ---- Audio ----------------------------------------------------------
audio_driver = "alsathread" # "wasapi" on Windows, "coreaudio" on macOS
audio_sync = "true"
audio_latency = "64"
audio_resampler = "sinc"
# ---- Latency --------------------------------------------------------
run_ahead_enabled = "false" # enable per game; 1 frame is usually enough
run_ahead_frames = "1"
run_ahead_secondary_instance = "true"
video_frame_delay = "0"
video_frame_delay_auto = "true"
# ---- Input ----------------------------------------------------------
input_autodetect_enable = "true"
input_menu_toggle_gamepad_combo = "2" # 2 = hold Start+Select to open the menu
menu_swap_ok_cancel_buttons = "false"
# ---- Saves & states -------------------------------------------------
savestate_auto_save = "false"
savestate_auto_load = "false"
savestate_thumbnail_enable = "true"
sort_savefiles_enable = "true"
sort_savestates_enable = "true"
# ---- Overrides & options --------------------------------------------
config_save_on_exit = "true" # persist global changes on quit
game_specific_options = "true" # honor per-game .opt files
auto_overrides_enable = "true"
auto_remaps_enable = "true"
# ---- RetroAchievements (optional) -----------------------------------
cheevos_enable = "false"
cheevos_hardcore_mode_enable = "false"
# ---- Menu -----------------------------------------------------------
menu_driver = "ozone"
rgui_show_start_screen = "false"What to back up
Back up the things you cannot re-download: retroarch.cfg, the entire config/ folder (your overrides, remaps, and .opt files), and saves/ (battery saves and memory cards). Save states in states/ and playlists are nice to keep but reproducible. Do not bother backing up cores/, which the updater refetches in minutes, or your BIOS, which you should still have from the hardware you dumped. One command does it:
tar -czf retroarch-backup.tar.gz \
~/.config/retroarch/retroarch.cfg \
~/.config/retroarch/config \
~/.config/retroarch/savesWhere to go from here
You now have the model, not just the recipe: RetroArch is a host, cores are the programs, info files are the paperwork, BIOS files are the keys, and overrides are how you keep a hundred systems from stepping on each other. From here, deepen it at the source. The libretro documentation has a per-core library page for every core with its exact options and firmware, the buildbot is where every binary lives, and the forums are where regressions like the 2025 N64 mess get diagnosed in real time. If you would rather offload the frontend entirely, a dedicated distro like Batocera ships all of this pre-wired, and on the go the same cores run on the ARM handhelds we keep benchmarking. The empty room is only empty until you furnish it. Now you know where the furniture goes.
Questions the search bar asks me
- What's the difference between a RetroArch core and an emulator?
- A core is an emulator (or game engine) ported to the libretro API and shipped as a shared library — a .dll, .so, or .dylib. RetroArch itself emulates nothing and needs at least one core to run anything. Most cores, such as Snes9x, mGBA, and Genesis Plus GX, are the same code as their standalone versions with the platform I/O swapped for libretro calls.
- Which PlayStation core should I use, and what BIOS does it need?
- Use Beetle PSX HW for accuracy and upscaling, or PCSX ReARMed on weak ARM handhelds. Beetle PSX HW reads scph5500.bin (JP), scph5501.bin (US), or scph5502.bin (EU) from the system folder, and falls back to bundled OpenBIOS if none is present. The libretro docs recommend setting PGXP to 'memory only' and internal resolution to 2x as the sweet spot.
- Why won't my N64 games load in 2026?
- A regression introduced early in 2025 in the main mupen64plus-next core broke certain titles — the libretro forums reported Stunt Racer 64 and World Driver Championship no longer loading, with users reverting to the January build. Fixes: switch to ParaLLEl N64, change the graphics plugin to ParaLLEl-RDP or Angrylion, or roll back to a January 2025 build from the buildbot.
- How many cores can RetroArch run, and where do I get them?
- Well over a hundred. RetroArch 1.22.2 (November 2025) installs them via Online Updater then Core Downloader, or you can pull them by hand from buildbot.libretro.com. Always run Update Core Info Files after a manual install, or BIOS detection and the content scanner will not work correctly.
- Do core options and overrides survive a core update?
- Overrides (config/<Core>/*.cfg files) and input remaps persist across updates, but a core update can reset core-option (.opt) defaults, so keep your tuned .opt files backed up. Enable game_specific_options = true and save Core or Game Overrides rather than editing the global retroarch.cfg, which keeps one core's settings from corrupting another's.