-
Notifications
You must be signed in to change notification settings - Fork 18
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.
Retro games are off until you enable them in the Moonbase admin panel. Every game endpoint returns nothing until the feature is on.
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.
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.
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 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.
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.
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 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.
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.
"Cores" are the EmulatorJS runtime and the per-system emulator files. The player looks for them in this order:
- A custom URL you set in the admin panel
- Self-hosted files installed on your server
- 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.
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 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.
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.