RPCS3 (PS3 emulation) in ES-DE¶
How the PlayStation 3 emulator RPCS3 is set up on av under the guest
account, launched from ES-DE inside the Sunshine/Moonlight + gamescope gaming
session. This sits entirely in the gaming stack (docs/gaming/), separate from
the homelab; nothing here runs as root and nothing touches the homelab services.
The gaming session is under
guest(UID 1001). Admin access is viassh guest@localhost(skill-lava's key is inguest'sauthorized_keys).guest's shell is bash.
Where things live¶
| Thing | Path |
|---|---|
| RPCS3 AppImage | ~guest/Applications/rpcs3-*.AppImage |
| Global config | ~guest/.config/rpcs3/config.yml |
| Per-game configs | ~guest/.config/rpcs3/custom_configs/config_<SERIAL>.yml |
| Controller config | ~guest/.config/rpcs3/input_configs/global/Default.yml |
Firmware (dev_flash) |
~guest/.config/rpcs3/dev_flash/ (v4.93) |
| PPU/SPU cache + log | ~guest/.cache/rpcs3/ (RPCS3.log, cache/<SERIAL>/) |
| Patches | ~guest/.config/rpcs3/patches/ |
| ES-DE data | ~guest/ES-DE/ (custom_systems/, gamelists/, downloaded_media/) |
| ROMs | /opt/games/roms-flat/<system>/ (~guest/ROMs → this; group gamers) |
| PS3 ROMs | /opt/games/roms-flat/ps3/ |
Current build: RPCS3 v0.0.41 (rpcs3-v0.0.41-19564-700ca262), firmware 4.93.
Install¶
RPCS3 is a standalone emulator — not a RetroArch core (the libretro RPCS3 core is defunct). ES-DE launches the standalone AppImage.
- AppImage — download the latest Linux build and drop it in
~/Applications(ES-DE's find-rule matches~/Applications/rpcs3*.AppImage). No root needed; the AppImage self-mounts (FUSE works on this host). - PS3 firmware — official Sony PUP, installed headlessly (no GUI):
# firmware from https://www.playstation.com/en-us/support/hardware/ps3/system-software/ # (dus01.ps3.update.playstation.net/.../PS3UPDAT.PUP) cd ~/Applications ./rpcs3-*.AppImage --headless --installfw ~/Downloads/PS3UPDAT.PUP # verify: head -1 ~/.config/rpcs3/dev_flash/vsh/etc/version.txt # -> release:04.9300:--installfwalone opens a GUI confirmation that blocks headless;--headlessbypasses it. TheQCommandLineParser: option not expecting valueswarning is benign.
The AMD Radeon 8060S (RADV, Strix Halo) is the Vulkan device — RPCS3 defaults to Vulkan, which is correct here.
ES-DE integration¶
A custom ps3 system overrides the bundled one so any .iso (or .ps3
directory) in ROMs/ps3 launches straight into standalone RPCS3 — the same
"drop a file in the folder and it just works" behaviour as Dolphin/gc.
~guest/ES-DE/custom_systems/es_systems.xml (the ps3 block):
<system>
<name>ps3</name>
<fullname>Sony PlayStation 3</fullname>
<path>%ROMPATH%/ps3</path>
<extension>.desktop .iso .ISO .ps3 .PS3 .ps3dir .PS3DIR</extension>
<command label="RPCS3 ISO (Standalone)">%EMULATOR_RPCS3% --no-gui %ROM%</command>
<command label="RPCS3 Directory (Standalone)">%EMULATOR_RPCS3% --no-gui %ROM%</command>
<command label="RPCS3 Shortcut (Standalone)">%ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM%</command>
<command label="RPCS3 Game Serial (Standalone)">%EMULATOR_RPCS3% --no-gui %RPCS3_GAMEID%:%INJECT%=%BASENAME%.ps3</command>
<platform>ps3</platform>
<theme>ps3</theme>
</system>
The default (first) command is the ISO launcher; the Directory command is
identical, so folder ("JB folder") games renamed with a .ps3 extension launch too.
Adding a PS3 game¶
1. Decrypted ISO (the common case — Vimm's .dec.iso)¶
7z e -y "/home/guest/Downloads/<game>.7z" "*.iso" -o/opt/games/roms-flat/ps3/
# (drop the ".dec" from the name if present)
2. Encrypted ISO (needs the disc key)¶
If a plain .iso fails with Invalid or unsupported file format: EBOOT.BIN,
it's disc-encrypted (EBOOT magic isn't SCE\0/7fELF). RPCS3 will decrypt it
on the fly if you drop the 32-hex disc key next to the ISO as a .dkey with
the same basename:
cp "<game>.key" "/opt/games/roms-flat/ps3/<game>.dkey" # 32 hex chars, e.g. redump .dkey
# RPCS3 log then shows: "ISO: init: Found matching key file: ...dkey"
3. Boot-test to get the serial (headless, no display needed)¶
cd ~/Applications
: > ~/.cache/rpcs3/RPCS3.log
xvfb-run -a ./rpcs3-*.AppImage --headless "/opt/games/roms-flat/ps3/<game>.iso" &
sleep 8; grep -aE 'SYS: (Title|Serial|Version)' ~/.cache/rpcs3/RPCS3.log
# a serial dir appearing under ~/.cache/rpcs3/cache/<SERIAL>/ == it really booted
pkill -f 'rpcs3-.*AppImage'; pkill Xvfb
4. Scrape metadata + art (Skyscraper → ScreenScraper → ES-DE)¶
Input must be passed with -i (gather mode's default input is the RetroPie
path, which doesn't exist here):
Skyscraper -p ps3 -s screenscraper -i ~/ROMs/ps3 --flags unattend
Skyscraper -p ps3 -f esde -i ~/ROMs/ps3 --flags unattend,nobrackets
Per-game configs & tuning¶
Per-game configs live at ~/.config/rpcs3/custom_configs/config_<SERIAL>.yml
(a full copy of config.yml with overrides). RPCS3 loads them automatically for
that serial — not config/custom_configs/ (a common wrong guess).
Global defaults applied to all games: Resolution Scale 150%, Anisotropic 16×, Keep pads connected: true (survives transient controller drops).
Working titles¶
| Game | Serial | Status | Key settings |
|---|---|---|---|
| Resistance: Fall of Man | BCUS98107 | Flawless | stock (global defaults only) |
| Metal Gear Solid 4 | BLUS30109 | Playable | see below |
| L.A. Noire | — | not via RPCS3 | use Steam (see below) |
MGS4 (BLUS30109) — the settings that made it playable¶
Wiki-recommended plus what we found by testing:
- SPU XFloat Accuracy: Accurate — the fix for the early-gameplay freeze
(same symptom RPCS3 issue #16920; the wiki's crash-fix patch does not help
and doesn't match our decrypted dump's EBOOT hash anyway).
- Frame limit: PS3 Native, Write Color Buffers: true,
Accurate RSX reservation access: true, ZCULL Relaxed
(Relaxed ZCULL Sync: true + Accurate ZCULL stats: false).
- Libraries Control: ["libvdec.sprx:lle"] — required for FMV cutscenes.
- Memory-safety (see swap section): LLVM Precompilation: false,
Max LLVM Compile Threads: 4.
Controller¶
The gaming session is driven over Moonlight, so the physical controller
arrives as Sunshine's virtual Xbox pad. RPCS3 binds Player 1 to it by exact
name in input_configs/global/Default.yml:
Player 1 Input:
Handler: SDL
Device: "Xbox One S Controller 1" # = SDL's GameControllerDB name for the Sunshine pad, + " 1"
RPCS3 auto-fills the standard Xbox button map when the Config: block is omitted.
- This one config covers every Moonlight session regardless of the physical controller — Sunshine always presents the same virtual pad.
- Controllers plugged directly into
avreport their own names, so each distinct model needs a one-time selection (RPCS3 binds by exact device name). To find a device's exact name: launch with a placeholder SDL config and readSDL: Found game pad N: name='...'from the log — RPCS3's device string is"<that name> 1".
Memory / swap (important on this host)¶
Strix Halo carves most of the 128 GB unified memory as GPU VRAM, so the OS sees only ~31 GB system RAM, and the distro's only swap is zram (compressed, in that RAM — no real overflow). A heavy game (MGS4) exhausted RAM+zram and got OOM-killed.
Fix: a 64 GB disk-backed swapfile as overflow (priority below zram). Created
by tools/setup-gaming-swap.sh (Btrfs-aware: dedicated /swap subvolume,
NOCOW, persisted in fstab with nofail). Run once:
LLVM Precompilation: false + capped compile threads also cut peak RAM.
Steam games in ES-DE (and why L.A. Noire lives there)¶
Steam games appear in ES-DE's steam system as tiny launcher scripts in
ROMs/steam/:
# ROMs/steam/<Game>.sh
#!/bin/bash
systemctl --user start --no-block gamescope-steam-game@<APPID>.service
110800).
L.A. Noire is intentionally not on RPCS3. Both PS3 editions are rated
"Ingame" (not "Playable") in RPCS3's compat DB — they deadlock in the
MotionScan video decoder (libsmvd2 throws sys_mutex … CELL_ESRCH: the
decoder's threads reference a mutex RPCS3 has already torn down → the game waits
forever on an event that never fires). We climbed the whole ladder — RPCS3
Scheduler beat an earlier title-screen deadlock, SPU interpreter + libvdec/
libsmvd2/libavcdec LLE got it into the first case — but the decoder wall is an
upstream emulator bug (open issues #9087, #14513), not a config we can fix. The
native Steam version sidesteps it entirely.
Check any game's status before sinking time into it:
curl -fsSL "https://rpcs3.net/compatibility?g=<SERIAL>&api=v1" # look for "status": "Playable" vs "Ingame"
Operations & troubleshooting¶
- RPCS3 launches in-session only.
--no-guican't create its Vulkan window when started over SSH — it blocks at window creation. ES-DE launches it as a child of the desktop session, so it renders fine. (Boot logic can be verified headlessly with--headless+ Xvfb; rendering can't.) - Kill a hung RPCS3 (the process re-execs as
AppRun.wrapped, so match by comm): - ES-DE is service-managed — killing the process just makes it relaunch. To actually stop/restart it (e.g. to re-scan the library):
- Log:
~/.cache/rpcs3/RPCS3.log(note:.cache, not.config). RPCS3 buffers it and doesn't flush the tail on SIGKILL, so mid-run state is best read from side-effects (acache/<SERIAL>/dir = it booted) rather than the log tail. - Gaming is sacred: don't claim Sunshine's ports (47984–48010, 1716) or touch
display/session/audio config from homelab work. See
CONTEXT.md.
Open follow-ups¶
- Two 8BitDo Pro 3 controllers used directly on
avstill need their exact device names captured (put them in X-input mode, then readSDL: Found game pad). - Redundant game
.7zarchives in~guest/Downloads/(~68 GB) can be deleted to reclaim space; the extracted ISOs are what's used.