Skip to content

Retro Games

RadicalMuffinMan edited this page Jul 16, 2026 · 2 revisions

Retro Games

Moonbase can turn a folder of ROMs into a browsable game library that plays right in the browser, using a bundled EmulatorJS runtime. Games play with zero setup by default, because the emulator files load from a public CDN. Self-hosting those files is optional.

Because ROM files are not a media type Jellyfin or Emby understand, the plugin does not index games in the normal library database. Instead it reads your game folders directly off disk each time.

Turning it on

Retro games are off until you enable them in the Moonbase admin panel. Every game endpoint returns nothing until the feature is on.

Folder layout

Pick your game libraries in the Moonbase admin panel. If you have not picked any, the plugin falls back to auto-detecting libraries whose name contains "game", "rom", or "emulator". Inside a game library, use one folder per system, and one folder per game:

Games/
  SNES/                 one folder per system
    bios files here     loose BIOS files for that system
    Super Mario World/  one folder per game
      Super Mario World.sfc
    Chrono Trigger.sfc  loose ROMs also work
  Genesis/
    Sonic.md

Each top-level folder under the library is treated as a system. A game can be a folder containing a ROM, or a loose ROM file sitting directly in the system folder. The game title comes from the game folder name, or the file name for loose ROMs.

Supported systems

Systems are matched by the system folder name first, then by the ROM file extension.

System Apple TV Moonfin-Core webOS / Tizen
NES / Famicom Yes Yes Yes
SNES / Super Famicom Yes Yes Yes
Game Boy / Game Boy Color Yes Yes Yes
Game Boy Advance Yes Yes Yes
Sega Genesis / Mega Drive Yes Yes Yes
Sega Master System Yes Yes Yes
Sega Game Gear Yes Yes Yes
PlayStation Yes Yes Yes
Nintendo 64 No Yes Yes
Nintendo DS No Yes Yes
PSP No Yes No
Virtual Boy No Yes Yes
Atari 2600 No Yes Yes
Atari 7800 No Yes Yes
Atari Lynx No Yes Yes
WonderSwan No Yes Yes
Neo Geo Pocket No Yes Yes
PC Engine / TurboGrafx-16 No Yes Yes

The Moonfin-Core column covers the web, mobile, desktop, and Android TV clients, which all play the same set. webOS / Tizen needs a supported TV version, covered below.

Platform support

Most Moonfin clients run games in a WebView through EmulatorJS and can play whatever the server serves. Two platforms have limits worth knowing about.

Apple TV

Apple TV plays only the eight systems marked Yes in its column. It has no WebView (well it DOES but Apple does not allow any third party apps to use, sory), so it plays games through a native bridge with the emulator cores built into the app, and App Store rules don't allow downloading cores at runtime. The set that ships with the app is the set you get. Picking a game from any other system shows a "not supported" message instead of playing.

Smart-TV (webOS and Tizen)

webOS and Tizen CAN play games, but only on webOS 5 or newer and Tizen 5 or newer. Emulator cores are WebAssembly, and the browsers on older TVs (webOS 4 and below, Tizen 4 and below) have no WebAssembly at all, so games cant run there.

Smart TVs also run the emulator without threading, so PSP will not play there even on a supported TV version. Every other system in the table works.

Not supported anywhere

Multi-file disc sets (.cue with .bin, or .m3u multi-disc) don't work, and neither do heavier systems like Saturn, Sega CD, 32X, and arcade/MAME. Disc systems work with single-file images only (for example .chd or .pbp for PlayStation, .cso or .iso for PSP). PlayStation needs a BIOS placed in its system folder.

ROMs and archives

ROMs stream to the player with range support, so large files can seek and resume. Compressed ROMs are extracted on the server on the fly, so the original archive is left untouched. Only .zip and .7z archives are supported, and only single-file archives (one ROM inside). The .7z support uses the bundled SharpCompress library that ships next to the plugin.

BIOS files

A BIOS is any non-ROM file at the top of a system folder, with an extension like .bin, .bios, .rom, .img, .sys, or .bs. When a game needs a BIOS, the plugin lists it on the game and streams it to the player alongside the ROM.

Emulator cores

"Cores" are the EmulatorJS runtime and the per-system emulator files. The player looks for them in this order:

  1. A custom URL you set in the admin panel
  2. Self-hosted files installed on your server
  3. The public EmulatorJS CDN (the default, so games work out of the box)

Self-hosting is worth it if you want games to work without reaching out to the CDN. You can install the cores two ways from the admin panel:

  • Install downloads the cores bundle in the background (it is large, around 290 MB). The download starts and the panel shows progress.
  • Upload installs the cores from a zip you provide.

The cores status shows whether they are installed or still downloading.

Saved games

Save states and battery saves sync per user. When you save in the player, the blob uploads to the server keyed to your account and the specific game, so your progress follows you to another device. Saves are capped at 32 MB each.

Game details

Game info (overview, genre, developer, publisher, year, players, region) is filled in automatically from keyless public databases (the LaunchBox Games Database and libretro's databases). Box art and screenshots come from the libretro thumbnail library, downloaded and cached on the server the first time a game is shown. This all happens entirely on the server, and the client never handles the ROM file itself. Also there is no way to update the metadata, the best way to make sure it matches is to ensure the file name is something that the databases recognize.

Troubleshooting

If a library is not detected, the admin-only GET /Moonfin/Games/Debug endpoint dumps what the plugin sees: whether games are enabled, which library ids are configured, every library folder and whether it exists on disk, and the libraries it resolved as game libraries.

See the API Reference for the full endpoint list.

Clone this wiki locally