Emulator setup
The one-time desktop session each emulator needs before single game launches work: BIOS, firmware, keys and controllers.
Single game launches reuse whatever configuration the emulators already have, so before a game will launch straight from RomM, each emulator needs a one-time setup pass. Launch the container in desktop mode from the RomM web interface, then open each emulator you plan to use from that desktop. Run its setup wizard, configure your controller, and install any system files or firmware it needs. Play an actual game to confirm everything works, and while you are there, adjust graphics and audio settings to your liking. Everything you set up here is stored in the container's home directory and carries over automatically when you launch games directly.
This is the step most first launches fail on. If you landed here from a failed activate rather than by choice, the Quickstart covers where this fits in the rest of the setup, and Troubleshooting covers what a missing BIOS or key actually looks like when a game refuses to launch.
Getting files into the container
Firmware blobs, decryption keys, BIOS images, and system modules can be dragged and dropped straight into the browser window. This upload path is for system files, not ROMs. Games come from your RomM library. Once uploaded, use the pcmanfm file manager or a foot terminal on the desktop to move files into the directories each emulator expects.
Drag-and-drop is not the only option. /config is the volume every deployment
already mounts (see Running the container), and it acts as
the container's home directory. So anything you place on the host at the
matching path shows up inside the container automatically, with no upload
needed. This is especially useful for RetroArch: its shared BIOS directory is
RETROARCH_SYSTEM_DIR (default /config/.config/retroarch/system, see
Configuration). Every RetroArch core
(RetroArch's term for the plug-in that emulates one specific system) reads
from this one folder, so seeding it on the host covers every core at once.
The per-emulator sections below give the matching path for each standalone
emulator's BIOS, keys, or firmware, for example /config/.local/share/flycast
for Flycast, or /config/.local/share/Cemu for Cemu's keys.txt.
Pre-seeding a path does not skip a standalone emulator's setup wizard. Emulators outside RetroArch each keep track of their own BIOS or firmware location in their own settings, rather than reading it from the broker. So most of them still need one visit to their setup screen to point at or select the file, even when that file is already sitting in the expected directory. Pre-seeding only saves you the upload step; it doesn't skip the one-time wizard visit described for each emulator below.
Leaving desktop mode
You don't have to close the emulators you opened before ending the session. Exiting desktop mode closes everything you started from the desktop, whether or not you left its window open. So a RetroArch or PCSX2 window you forgot about won't keep running in the background (and won't keep rendering into the next session's stream) afterwards.
Each app gets DESKTOP_STOP_WAIT seconds (default 15, see
Configuration) to shut down on its own before
it gets killed outright. That grace period is what lets an emulator finish
writing the settings you just changed. Raise the value if an emulator you use
needs more time than that to save its settings on exit.
Controllers
Controllers behave the same in the desktop view as they do in a single game launch. So if a controller works in a real game on the desktop, it will work the same way when RomM launches that game directly. Always test a real game with a real controller before you call an emulator's setup done.
Dolphin
Dolphin comes with default controller profiles and settings already set up inside the container on first launch. The only settings you should need to change are graphics options, such as internal resolution and rendering mode.
Dolphin may need to be opened and closed once before its window gets a normal titlebar (the bar across the top with the close and minimize buttons). If the window has no titlebar on first launch, close it and reopen it to continue configuration.
Eden
Eden won't run games until you install prod keys and firmware. Go to Tools, select Install decryption keys, and point it at your uploaded prod keys. Then select Install firmware and point it at the folder or file you uploaded.
Controller profiles are already set up for Eden the first time the container starts. You may also want to adjust graphics and audio settings, then run a game to confirm.
Xemu
Xemu needs three specific files. By default, it launches straight into the settings menu that asks for them. Upload your files, then select the MCPX boot ROM, the flash ROM (BIOS), and the hard disk drive image.
The first time the container starts, it converts the hard disk drive to raw format and keeps a backup of the original qcow2 image in the same folder. The broker needs both files to extract and restore your saves, so leave them where they are.
Controller profiles are set up automatically the first time the container starts. Adjust graphics and audio to your liking, then test a game.
You need to relaunch Xemu after its default files are set up, before it will boot anything.
Xenia
Xenia (Xbox 360) runs through the Xenia Edge. Controllers work out of the box through SDL (the library that lets emulators read game controllers), so the desktop visit is mostly about the profile and graphics settings.
Xenia needs a profile before it can save anything. The first time it starts with no profile, a No Profiles Found dialog offers to create one. Launch Xenia once from the desktop, accept that prompt (or use the profile menu's Create new...), enter a gamertag, and close Xenia. The new profile signs in automatically, and Xenia remembers it in its own settings. So every later launch signs into that profile by itself, and games see a logged-in Xbox Live profile to save against.
During a single game launch, the game's own dialogs (sign-in, message boxes,
the on-screen keyboard) show up inside the game's window. The player answers
sign-in and message boxes with the controller, the same as on a console. The
on-screen keyboard is the exception: the controller can accept the text the
game suggests or cancel, but typing anything else needs a keyboard in the
browser. Xenia picks the storage device (the hard drive) by itself unless you
turn on storage_selection_dialog in its settings. The profile prompt is
different: it's Xenia's own window, and a game launched without a profile
would get stuck behind it with no way to dismiss it.
Set your graphics options and test a real game from the desktop before launching it through RomM.
You must launch Xenia once from the desktop to create a default Xbox Live
profile for signing into games. Without it, single game launches stall on the
profile prompt and games cannot save. Single game launches keep all Xenia
data, including the profile, under /config/xenia; the profile has to be
created in that same folder to be the one games boot with.
DuckStation
DuckStation runs a setup wizard the first time you launch it. Upload your BIOS, select it for the BIOS folder, and skip the game directory step. For controller setup, make sure you pick the right SDL devices: SDL 0 for player 1 and SDL 1 for player 2.
Finish by setting the graphics options you want (renderer, internal resolution, enhancements), then test a game.
shadPS4
shadPS4 needs everything below before it can launch games.
Launch shadps4qt and open the version manager in the top right. From that menu, pick the version of shadPS4 you want to use; you'll use this same menu later to pull updates. The broker always uses the latest version you've downloaded, preferring a pre-release if one is available. Once a version downloads, the container automatically extracts its AppImage (a self-contained app format) so it can run inside Docker.
Controllers are pre-configured for shadPS4.
Most games need sys_modules, PS4 system library files that shadPS4 doesn't
ship with. Upload them so they end up in
/config/.local/share/shadPS4/sys_modules (shadPS4 creates this folder itself
the first time it launches).
You may also want to point DLC content at your /romm folder in the
container. This depends entirely on how you have that folder organized.
As with the other emulators, set graphics options to taste and confirm with a real game.
shadps4qt is only a desktop manager for shadPS4's settings. You configure things through it, but the actual programs single game launches use are the shadPS4 versions it downloads.
shadPS4 boots an eboot.bin file out of an extracted game folder, and it
can't boot a .pkg file directly. So a .pkg ROM (or a .7z/.zip/.rar
archive containing one) has to be unpacked by pkg_extractor before it can
run, and the extraction cache is where that unpacked copy goes. Set
SHADPS4_CACHE_ENABLED=true to let shadPS4 boot those formats: the first
launch extracts the ROM, and every later launch reuses that extraction. The
cache size is capped by SHADPS4_CACHE_MAX_GB (default 30GB), and the oldest
extraction gets evicted first once you hit that limit. The cache lives at
/config/.local/share/shadPS4/extracted. If you enable it, point a dedicated
bind mount or Docker volume at that path, so it doesn't compete with the rest
of /config for space.
An archive is the expensive case: its unpacked .pkg file and
pkg_extractor's own output both sit on disk at the same time at the peak.
So it needs roughly twice the archive's size in free space, even though only
about the archive's size is kept afterward. If a launch won't fit, either
under SHADPS4_CACHE_MAX_GB or in the actual free space on that filesystem,
it's refused up front instead of filling the disk for several minutes and
then failing with a write error.
Leave SHADPS4_CACHE_ENABLED off (its default) and a .pkg or archive ROM is
refused outright, rather than being extracted and thrown away on every
launch. That means only natively bootable formats work: a game folder, a bare
eboot.bin, or a .zar file. While extraction is running,
GET /api/session/status reports extraction_phase as
"extracting_archive" or "extracting_pkg" (see
Configuration).
PCSX2
PCSX2 runs a setup wizard much like DuckStation's. Upload your BIOS files and select them, skip the game folder step, and for controller setup pick the right SDL devices: SDL 0 for player 1 and SDL 1 for player 2.
Set your graphics preferences and test a game before moving on.
PPSSPP
PPSSPP needs no BIOS: PSP support is fully HLE (high-level emulation, meaning it doesn't need real PSP system files to run games). Controllers work out of the box through SDL, so the desktop visit is mostly about graphics and audio.
PPSSPP is hotkey-driven like Dolphin: the broker triggers save and load
through PPSSPP's keyboard shortcuts, always using state slot 1. Save data and
states live under PSP/ in PPSSPP's config root, $XDG_CONFIG_HOME/ppsspp
(default /config/.config/ppsspp).
Prefer RetroArch's ppsspp core for PSP launches instead: it's the same
underlying emulator engine, just with better controller and save-state
handling (see Supported emulators). Set up the
standalone version anyway if you want it available too; it needs no extra
files either way.
Archived PSP ROMs (.7z, .zip, .rar) boot once PPSSPP_CACHE_ENABLED=true
is set: the broker extracts one on its first launch and keeps it, capped by
PPSSPP_CACHE_MAX_GB (default 20GB). The RetroArch core reads zips on its
own and doesn't use this cache.
Set your graphics options and test a real game before moving on.
RetroArch
RetroArch is pre-configured, and cores are downloaded automatically as you request launches. You may still want to adjust per-core or general settings from RetroArch's main menu on the desktop. You can reach that same menu during a single game launch by pressing F1.
BIOS files and other RetroArch assets vary too much to cover here in full. The RetroArch core manifest lists what each core this project maps to a platform actually needs. For the full, authoritative details on a specific core, check libretro's own core-specific BIOS documentation.
RPCS3
RPCS3 needs its firmware installed from File > Install Firmware. Controllers are already set up.
Adjust graphics settings to your liking and run a game to confirm.
Special note: Saving a state in RPCS3 always closes the game, and there's no way to load a state while the game is running either. So a single game launch captures a state only on exit (using the same in-game save-state hotkey a player would use), and it resumes at the next launch by booting straight into that state, rather than loading the state afterward. RPCS3's IPC (its interface for outside programs to talk to it) has no command for saving or loading a state at all. The broker only uses that interface to confirm a launch actually reached a running game and, when a game's title ID can't be read from the file path alone, to look it up once the game is confirmed running.
A ROM stored as a
.7z,.zip, or.rararchive has to be extracted before it can boot, since RPCS3 can't boot an archive directly. So those formats need the extraction cache. SetRPCS3_CACHE_ENABLED=trueto boot them: the first launch extracts the ROM, and every later launch reuses that extraction. The cache size is capped byRPCS3_CACHE_MAX_GB(default 30GB), and the oldest extraction gets evicted first once you hit that limit. The cache lives at/config/.config/rpcs3/extracted. If you enable it, point a dedicated bind mount or Docker volume at that path, so it doesn't compete with the rest of/configfor space. If a launch won't fit, either underRPCS3_CACHE_MAX_GBor in the actual free space on that filesystem, it's refused up front instead of filling the disk for several minutes and then failing with a write error.Leave
RPCS3_CACHE_ENABLEDoff (its default) and an archived ROM is refused outright, rather than being extracted and thrown away on every launch. That means only natively bootable formats work:.iso, or an installed.pkg..pkgis unaffected either way: it always installs through its own installer, never through this cache. While an archive is extracting,GET /api/session/statusreportsextraction_phase: "extracting_archive".
Cemu
Cemu needs everything set up by hand: controller profiles, audio, and decryption keys.
- Launch Cemu once and close it so it creates its default directories.
- Upload your
keys.txtand place it in/config/.local/share/Cemu. - Launch Cemu and open controller settings. Select Wii U Pro Controller as the emulated controller. If that option isn't available, set it up as a Wii U GamePad instead, save, exit, and reopen the settings.
- Click the add button for the controller, select SDL as the driver type, and pick the first pad in the list of four. Confirm the controller works by moving the analog sticks and watching the live input display.
- Under General settings > Audio, make sure TV is set to Default Device. You may need to close and reopen this menu before the option appears; that gives Cemu time to detect the PulseAudio backend (the container's audio system).
Finish with your preferred graphics settings and test a game.
Cemu is finicky. Expect to launch it multiple times before all settings stick, and the controller profile menus are half broken: click the down arrows, click into the dropdowns, and navigate them with the keyboard to get them to behave.
Azahar
Controllers are pre-configured for Azahar. Open it from the desktop, set graphics and audio to your liking, and test a game to confirm.
Azahar stops rendering if the display resizes while it's in fullscreen, and the display resizes every time you resize your browser window. That's why single game launches start Azahar windowed instead, since a windowed game isn't affected. Keep this in mind on the desktop too: if you put Azahar into fullscreen yourself and then resize the browser, the picture freezes, and you have to leave fullscreen to get it back.
For 3DS, the RetroArch core is the better choice, and it's what a 3ds
launch uses by default. Azahar gives the broker no way to reach it from
outside its own process. So a standalone session has no save states, and it
shuts down with a hard kill rather than a clean exit, meaning only what the
game already wrote to its own save survives. The RetroArch core supports both
save states and a proper exit. Use standalone Azahar when you want its own
interface, and pick retroarch otherwise.
Flycast
Flycast needs the Dreamcast BIOS pair: dc_boot.bin and dc_flash.bin.
Upload them and place them in /config/.local/share/flycast, the same flat
directory that VMU (Dreamcast memory card) saves and save states live in.
Controllers are pre-configured. Set your graphics and audio preferences from the desktop and test a game.
A RetroArch core also covers Dreamcast (dc defaults to it) for anyone who
prefers RetroArch's shared save-state menu and hotkeys. Standalone Flycast
has no control socket (a direct channel for the broker to send it commands)
and no SIGTERM handler (the standard shutdown signal), so the only way the
broker can ask it to shut down cleanly is by sending an Alt+F4 keypress into
its window. That's also the only moment it writes a save state. That means,
like DuckStation, there's no mid-session save or load: a launch resumes from
whatever state was written on the previous clean exit, and the current
session's state gets written once, on exit. Use standalone Flycast for its
own interface and settings, and pick retroarch if you'd rather manage
Dreamcast alongside your other RetroArch cores.
ScummVM
Nothing to install here: ScummVM ships its own engines and needs no BIOS,
firmware, or keys. The games themselves are the setup. A ScummVM game is a
folder of data files rather than a single image, so the entries in your
RomM library for this platform have to be folders, one per game, and the
platform's fs_path has to resolve to the same files inside the container.
A game zipped into a single .7z, .zip, or .rar archive works too. The
broker extracts it on the first launch and keeps the result, capped by
SCUMMVM_CACHE_MAX_GB (default 10GB). See
Configuration.
There's no controller step either. These are mouse-and-keyboard games, played with the stream's own pointer and keyboard.
It's worth doing once from the desktop: open ScummVM, set the menu language you want, and play a game to confirm the pointer tracks. The broker follows that same language when it drives the save menu, and it pins the renderer and window settings the stream needs on every launch, so a game that behaves in a desktop session behaves the same way in a streamed one.
Not every engine can save mid-game. The broker's save and load actions drive ScummVM's Global Main Menu, and an engine that doesn't support saving while running declines the request: Gobliiins is the clearest example, since its gob engine has no save handler at all and passwords are the game's own progression system. Save state then reports a failure rather than pretending, while the game's own saves still travel in the archive and a boot-time resume still works.