Distrobox Gaming
Script to create a gaming focused Distrobox with all emulators pre-configured
#Distrobox Gaming
Ansible playbooks for an Arch-based distrobox named gaming. Sets up ES-DE,
standalone emulators (shadPS4 for PS4, Dolphin for GC/Wii, PCSX2 for PS2,
DuckStation for PS1, Flycast for Dreamcast, xemu for Xbox, RPCS3 for PS3,
PPSSPP for PSP, Azahar for 3DS, Eden for Switch, Cemu for Wii U, RetroArch, and
Supermodel for Sega Model 3), RetroArch cores, host-side Walker desktop
launcher rendering/install scripts, DLC/patch batch installers for PS3 and
Switch, per-game RPCS3 optimization configs, optional Wine-managed Xenia
Manager for Xbox 360, Hedge Mod Manager for Sonic mods, optional native
Unleashed Recompiled for Sonic Unleashed, and a minimal zsh + starship shell
inside the box.
Beyond the core emulators, a large set of opt-in roles (all never-tagged,
or run via a standalone install-*.yml playbook) add: Sega arcade (Model 1/2/3
via Wine frontends + Supermodel), native recomp/decomp ports (Ship of Harkinian,
2Ship2Harkinian, Starship, Render96ex, SpaghettiKart, Sonic P-06, Unleashed
Recomp, PrBoom-Plus Doom II RT), Windows/Wine games (Colin McRae Rally, OutRun
2006, Sega Rally, GT5 Master Mod, Metal Gear Master Collection fixes, and more),
and reproducible NexusMods mod-set roles per game. See docs/nexusmods.md,
docs/external-installers.md, and docs/rebuild-runbook.md.
#macOS
macos/ is a separate, native macOS baseline — ES-DE plus Dolphin, PCSX2 and
PPSSPP over Homebrew, with its own small Ansible playbook. It shares no code
with the Linux tree: no Distrobox, no Wine/Proton, no .so cores. Windows
software is permanently out of its scope. See macos/README.md
and macos/INSTALL.md.
Everything else in this file describes the Linux distrobox.
#Quick Start
cd ansible ansible-galaxy collection install -r collections/requirements.yml cp host_vars/localhost.yml.example host_vars/localhost.yml $EDITOR host_vars/localhost.yml ansible-playbook site.yml
For a full run with optional Xbox 360/Xenia Manager:
ansible-playbook site.yml ansible-playbook install-xenia.yml
#Commands
All commands run from the ansible/ directory:
ansible-playbook site.yml # full setup from scratch ansible-playbook reset-configs.yml # reset emulator configs without rebuilding ansible-playbook backup.yml # backup before destructive testing ansible-playbook restore.yml # restore from backup ansible-playbook refresh-shadps4.yml # update shadPS4 builds ansible-playbook install-xenia.yml # install/update Xenia Manager (optional) ansible-playbook install-hedgemodmanager.yml # install/update Hedge Mod Manager ansible-playbook install-pc-racing.yml # prepare/install optional Windows PC racing games ansible-playbook install-outrun-2006.yml # install/update OutRun 2006 ansible-playbook install-sega-rally-revo.yml # install/update Sega Rally Revo ansible-playbook install-sonic-p06.yml # install/update Sonic Project '06 ansible-playbook install-unleashed-recomp.yml # install/update Unleashed Recompiled
Tags allow running subsets:
ansible-playbook site.yml --tags check # host path and UID/GID validation ansible-playbook site.yml --tags create # create the distrobox ansible-playbook site.yml --tags bootstrap # install pacman + AUR packages ansible-playbook site.yml --tags shadps4 # install/update shadPS4 ansible-playbook site.yml --tags hedgemodmanager # install/update Hedge Mod Manager ansible-playbook site.yml --tags configure # configs, desktop entries, ES-DE ansible-playbook site.yml --tags scripts # deploy box helper scripts ansible-playbook site.yml --tags shell # deploy zsh + starship ansible-playbook site.yml --tags verify # post-setup assertions ansible-playbook reset-configs.yml --tags esde # reset only ES-DE ansible-playbook reset-configs.yml --tags configs # reset only emulator INIs ansible-playbook reset-configs.yml --tags desktop # reset only desktop entries ansible-playbook reset-configs.yml --tags shell # reset only zsh/starship
#Opt-in roles (skipped by default)
These roles touch your specific ROM/NAS layout or perform large downloads, so they only run when the matching tag is explicitly passed:
ansible-playbook site.yml --tags dlcs # install PS3 DLCs + Switch NSPs ansible-playbook site.yml --tags cheats # link Switch cheats to Eden ansible-playbook site.yml --tags rpcs3_configs # per-game RPCS3 tuning ansible-playbook site.yml --tags retroarch # download RA cores + assets ansible-playbook site.yml --tags pcsx2_textures # PCSX2 HD texture packs + per-game settings + .pnach patches ansible-playbook site.yml --tags pc_racing # prepare tested Windows PC racing games via Wine ansible-playbook site.yml --tags sonic_p06 # install Sonic Project '06 via system Wine ansible-playbook site.yml --tags unleashed_recomp # install native Unleashed Recompiled Flatpak ansible-playbook site.yml --tags ogm # render the ogm (omarchy-games-menu) catalog fragment
#Path Configuration
All paths are configurable via Ansible variables. Defaults match the current machine's NAS layout:
dg_box_name: gaming dg_host_uid: 1026 # NAS requires this UID dg_host_gid: 1026 dg_data_root: /mnt/data dg_box_home: /mnt/data/distrobox/gaming dg_external_games_root: /mnt/terachad/Emulators dg_roms_final_root: "{{ dg_external_games_root }}/ROMS_FINAL" dg_emudeck_root: "{{ dg_external_games_root }}/EmuDeck" dg_bios_root: "{{ dg_emudeck_root }}/Emulation/bios" dg_rom_root: "{{ dg_emudeck_root }}/roms" dg_rom_heavy_root: "{{ dg_emudeck_root }}/roms_heavy" dg_ps3_dlc_source: "{{ dg_rom_heavy_root }}/ps3-DLC" dg_switch_updates_source: "{{ dg_rom_heavy_root }}/switch_updates" dg_switch_cheats_source: "{{ dg_rom_heavy_root }}/switch_cheats"
For another machine, create ansible/host_vars/localhost.yml and override any
variable. Or pass overrides on the command line:
ansible-playbook site.yml -e dg_data_root=/home/me/gaming -e dg_external_games_root=/media/games
#GPU Preference (NVIDIA vs AMD iGPU)
On systems with both an NVIDIA dGPU and an AMD iGPU, emulators are forced to
use NVIDIA by injecting VK_ICD_FILENAMES into every desktop launcher and
ES-DE command. The distrobox is also created with --nvidia so NVIDIA drivers
are bind-mounted into the container. Controlled by dg_nvidia_enabled: true
in group_vars/all/gpu.yml. Set to false to disable.
For Steam/Proton, the launcher also exports LD_LIBRARY_PATH pointing only to
an Ansible-managed extraction of the matching lib32-nvidia-utils package.
Steam Runtime's entrypoint converts that into pressure-vessel app library paths
before launching Proton. This avoids a distrobox --nvidia edge case where
host 64-bit NVIDIA libraries can appear under /usr/lib32, breaking 32-bit
DXVK games such as Sonic Adventure DX and Castlevania Anniversary Collection.
Steam game compatibility research is tracked in
data/steam-proton-compat.json. Refresh it with
scripts/build-steam-proton-db.py and record source-backed local fixes in
data/steam-proton-overrides.json; see docs/steam-proton-compatibility.md.
#Resetting Configs
If you screw up your emulator configs (ES-DE, DuckStation, PCSX2, etc.) and want to restore to Ansible-managed defaults without reinstalling the box:
ansible-playbook reset-configs.yml # reset everything ansible-playbook reset-configs.yml --tags esde # reset only ES-DE ansible-playbook reset-configs.yml --tags configs # reset only emulator INIs ansible-playbook reset-configs.yml --tags shell # reset only zsh/starship
This re-applies seed_configs, desktop_apps, configure_esde, and
shell_config roles. Existing files are backed up automatically before
overwriting.
#Backup and Restore
Before destructive testing (e.g. rebuilding from scratch):
ansible-playbook backup.yml # commits container image + archives configs ansible-playbook restore.yml # prompts for timestamp, restores both
Backups are stored under $DG_BOX_HOME/backups/.
#UID/GID and Permissions
The NAS requires UID/GID 1026 for file access. The check_host role asserts
the host user matches dg_host_uid before proceeding. The container user
inherits the host UID/GID through distrobox.
Override for another machine:
# ansible/host_vars/localhost.yml dg_host_uid: 1000 dg_host_gid: 1000
#What Gets Configured
#Base setup
- Arch-based distrobox named
gamingwith--nvidiadrivers bind-mounted - Pacman and AUR emulator packages (see
group_vars/all/packages.yml) - ES-DE (emulationstation-de) as the frontend
- RetroArch plus 25 buildbot cores (fbneo, mednafen variants, etc.) and all 8 asset packs (info, assets, autoconfig, cheats, databases, shaders, overlays) — ~760 MB total
- Atari 2600, 5200, 7800 and Lynx as opt-in ES-DE systems
(
dg_atari_enabled, off by default) on cores the list already carried (docs/atari.md) - Minimal zsh + starship prompt inside the box
#Per-emulator
- Flycast high-resolution wrapper at
$DG_BOX_HOME/bin/flycast-hires - PCSX2: Vulkan @ 4x upscale (4K from PS2 480p), widescreen 16:9, 16x AF,
PS2 bilinear filtering, built-in widescreen patches enabled, full
Xbox-style Pad1 binding via SDL backend,
Select+Startshutdown hotkey - Dolphin 8BitDo Ultimate 2 defaults for GameCube and Wii profiles
- DuckStation Vulkan/PGXP/widescreen defaults
- xemu config plus BIOS/HDD links from
$DG_BIOS_ROOT - shadPS4 wrapper launching QtLauncher-managed builds, Driveclub-specific
CUSA00003.tomlconfig with v1.28 patch XML, PS4 11.00 sys_module symlinks
#DLCs, patches, and per-game tuning
-
PS3 DLCs and patches:
install_dlcsrole batch-extracts every .pkg from$DG_PS3_DLC_SOURCEinto RPCS3'sdev_hdd0/game/— bypasses the GUI-only installer limitation -
Switch updates and DLC: same role extracts NSPs from
$DG_SWITCH_UPDATES_SOURCEinto Eden's NAND at~/.local/share/eden/nand/user/Contents/registered/ -
Switch cheats:
switch_cheatsrole symlinks Atmosphere-format cheats from$DG_SWITCH_CHEATS_SOURCEinto Eden's load path -
Per-game RPCS3 configs:
rpcs3_per_game_configsrole scans installed PS3 games, queries the RPCS3 compatibility API, and writes tunedcustom_configs/<TITLE_ID>_config.ymlfor games with "Ingame" or "Loadable" status. Hand-curated overrides for known-problematic titles (Gran Turismo 6, Gran Turismo 5, Metal Gear Solid 4). -
PCSX2 HD texture packs + per-game settings + .pnach patches:
pcsx2_texturesrole symlinks per-game texture replacement directories into~/.config/PCSX2/textures/<SERIAL>/replacements/<link_as>/(no copy — textures live on NAS, PCSX2 caches in RAM after first load), symlinks.pnachpatch files into~/.config/PCSX2/patches/, mass-symlinks~/.config/PCSX2/cheats/from a NAS cheats source, downloads a curated list of public.pnachURLs (e.g. Silent's GT4 USA patches from his GitHub), and writes per-game override INIs to~/.config/PCSX2/gamesettings/<SERIAL>.ini. Initial configs cover Gran Turismo 4 (SCUS-97328) with Silentwarior112's HD HUD/UI pack + update 2.1- blocky-haze-fix overlay + Silent's adjusted triggers / GT3 cam / far
chase cam patches, and Enthusia Professional Racing (SLUS-20967) HD
textures. Adding more games is a YAML data change to
dg_pcsx2_texture_packs,dg_pcsx2_per_game_settings,dg_pcsx2_extra_patches, anddg_pcsx2_patch_urlsingroup_vars/all/pcsx2.yml.
Texture pack updates are a manual process — the source forums (GTPlanet, Nexus Mods, Silent's Blog) are Cloudflare-walled and Drive/MEGA links throttle scripted downloads. Check periodically:
- GT4 retexture mod: https://www.gtplanet.net/forum/threads/gran-turismo-4-retexture-mod-v2-2.408852/
- Silentwarior's HD HUD/UI pack: https://cookieplmonster.github.io/mods/gran-turismo-4/
- Silent's pnach patches: https://silentsblog.com/mods/gran-turismo-4/
When a new version drops, download manually and drop into the existing pack directory in your NAS — the role re-symlinks on next run.
- blocky-haze-fix overlay + Silent's adjusted triggers / GT3 cam / far
chase cam patches, and Enthusia Professional Racing (SLUS-20967) HD
textures. Adding more games is a YAML data change to
#Host-side launchers
- Repo-managed Walker desktop entries for every emulator, defined as data in
group_vars/all/launchers.ymland rendered via a single Jinja2 template. Each Exec line is wrapped with the NVIDIA-preference env vars. - Entries cover: ES-DE, Dolphin, DuckStation, PCSX2, PPSSPP, RPCS3, xemu, Eden, Cemu, Vita3K, shadPS4 (Driveclub + No Patch + GUI), Flycast, Xenia Manager, Sonic P-06, and Unleashed Recompiled when their wrappers exist.
- Ansible renders entries into
config/desktop/rendered/; it does not write into the host applications directory from inside the distrobox. Install or refresh host menu entries from the host with:
scripts/install-host-launchers.sh
The script validates every rendered .desktop file, skips optional apps that
are not installed in the box, removes stale installed entries for missing
optional apps, and restarts Walker if it is running.
#Optional
- Wine-managed Xenia Manager with .NET/VC++ runtimes for Xbox 360
#Helper Scripts (manual use)
The install_dlcs role also deploys standalone scripts into the box that you
can run manually for advanced tasks:
# List / download missing PS3 patches from PSN's public update server python3 $DG_BOX_HOME/scripts/check_ps3_updates.py \ "$DG_ROM_HEAVY_ROOT/ps3" \ --dlc-dir "$DG_PS3_DLC_SOURCE" --list python3 $DG_BOX_HOME/scripts/check_ps3_updates.py \ "$DG_ROM_HEAVY_ROOT/ps3" \ --dlc-dir "$DG_PS3_DLC_SOURCE" \ --download-dir "$DG_BOX_HOME/dlc-temp" --download # List outdated Switch games (Nintendo's CDN needs console auth, so no download) python3 $DG_BOX_HOME/scripts/check_switch_updates.py \ "$DG_ROM_HEAVY_ROOT/switch" \ --updates-dir "$DG_SWITCH_UPDATES_SOURCE" # Reorganize a messy switch_updates dump into per-title-ID folders # (handles .nsp/.nsz/.xci/.xcz; mods and non-patch files are left alone) python3 $DG_BOX_HOME/scripts/reorganize_switch_nsps.py \ "$DG_SWITCH_UPDATES_SOURCE" --dry-run
Note on Switch updates: Nintendo's update CDN requires device-specific
certificates from a hacked Switch. check_switch_updates.py only reports
what's outdated (using the public blawar/titledb version database) — you
source the NSPs yourself.
#Full PS3 update workflow
- Check what's outdated:
python3 $DG_BOX_HOME/scripts/check_ps3_updates.py \ $DG_ROM_HEAVY_ROOT/ps3 --dlc-dir $DG_ROM_HEAVY_ROOT/ps3-DLC --list
- Download missing patches to a temp dir (keeps the NAS dir read-only
until you review):
python3 $DG_BOX_HOME/scripts/check_ps3_updates.py \ $DG_ROM_HEAVY_ROOT/ps3 --dlc-dir $DG_ROM_HEAVY_ROOT/ps3-DLC \ --download-dir $DG_BOX_HOME/dlc-temp --download
- Review
$DG_BOX_HOME/dlc-temp, then copy into the canonical cache:rsync -av $DG_BOX_HOME/dlc-temp/ $DG_ROM_HEAVY_ROOT/ps3-DLC/
- Re-run the install_dlcs role to extract them into RPCS3:
cd ansible && ansible-playbook site.yml --tags dlcs
The extract_ps3_dlc.py extractor uses the PKG's filename version
(e.g. -A0122-V0100-) and compares against the destination's
PARAM.SFO VERSION to decide whether to re-extract. Re-running after
all patches are applied is a no-op.
#Capping a game at a specific patch version
Some PS3 games regress on current RPCS3 when patched to the latest version (GT6 is notorious — older RPCS3 builds broke above 1.12 or so). To cap a game at a specific patch level:
# Wipe the current patch content dir so the version check doesn't block rm -rf $DG_BOX_HOME/.config/rpcs3/dev_hdd0/game/<CONTENT_ID> # Re-extract only patches up to the target version python3 $DG_BOX_HOME/scripts/extract_ps3_dlc.py \ $DG_ROM_HEAVY_ROOT/ps3-DLC/<TITLE_ID> \ --max-version 01.12
--max-version skips any patch PKG whose filename-encoded version
exceeds the limit. Without the rm -rf first, the version-aware
idempotency check would refuse to downgrade.
#PS4 Game Layout
The expected layout is clean extracted title directories, not raw .pkg files:
$DG_PS4_ROM_ROOT/
CUSA00003/
eboot.bin
...
#Xenia Manager
Xbox 360 support uses Xenia Manager inside a dedicated Wine prefix.
ansible-playbook install-xenia.yml will:
- Enable
multilibinside the box - Install
wineandwinetricks - Create the Wine prefix with .NET and VC++ runtimes
- Download the latest Xenia Manager release
- Write the launcher wrapper and render its desktop entry
After that, launch Xenia Manager and use its Manage page to install Canary.
#Hedge Mod Manager
Sonic mod support uses Hedge Mod Manager 8 built natively inside the distrobox,
not host Flatpak. The default site.yml run installs it; rerun only that role
with:
ansible-playbook install-hedgemodmanager.yml
The wrapper is written to {{ dg_box_home }}/bin/hedge-mod-manager.
It sees the same Steam install and external library paths as Steam inside the
box, including the Proton prefixes under steamapps/compatdata.
#PC Racing Games
Windows PC racing games are optional and live outside the normal rebuild path. They use system Wine inside the distrobox:
ansible-playbook install-pc-racing.yml
The install root is {{ dg_pc_racing_install_root }}; per-game prefixes stay
under {{ dg_pc_racing_prefix_root }}.
Installer GUIs are only launched when explicitly requested with
-e dg_pc_racing_run_installers=true.
#Sonic Project '06
Sonic P-06 is an optional Windows Unity fangame install managed outside Steam with system Wine, DXVK, core fonts, GStreamer codecs, and a dedicated prefix:
ansible-playbook install-sonic-p06.yml
The source is the already extracted Silver Release under
{{ dg_sonic_p06_source_dir }}. The managed copy lives at
{{ dg_sonic_p06_install_root }}.
#Project Structure
ansible/ # Ansible playbooks and roles (primary)
site.yml # full setup playbook
reset-configs.yml # config-only reset playbook
backup.yml / restore.yml # backup and restore
refresh-shadps4.yml # standalone shadPS4 update
install-xenia.yml # standalone Xenia Manager install
install-hedgemodmanager.yml # standalone Hedge Mod Manager install
install-pc-racing.yml # optional Windows PC racing setup
install-outrun-2006.yml # focused OutRun 2006 install
install-sega-rally-revo.yml # focused Sega Rally Revo install
install-sonic-p06.yml # optional Sonic Project '06 setup
install-unleashed-recomp.yml # optional Unleashed Recompiled install
group_vars/all/ # all dg_* variable defaults
main.yml # paths, UID/GID, box identity
packages.yml # pacman + AUR package lists
emulators.yml # per-emulator INI settings
esde.yml # ES-DE system definitions
launchers.yml # rendered host desktop launcher definitions
ogm.yml # ogm (omarchy-games-menu) catalog metadata
gpu.yml # NVIDIA preference config
shadps4.yml # shadPS4 release / path config
xenia.yml # Xenia Manager config
hedgemodmanager.yml # Hedge Mod Manager source-build config
pc_racing.yml # Windows PC racing source/install metadata
sonic_p06.yml # Sonic Project '06 Wine config
unleashed_recomp.yml # Unleashed Recompiled source staging config
pcsx2.yml # PCSX2 texture packs and per-game overrides
host_vars/localhost.yml.example # machine-specific overrides template
roles/ # one role per setup phase
check_host/ # host validation
create_box/ # distrobox creation (--nvidia)
bootstrap_packages/ # pacman + AUR packages
link_storage/ # BIOS/firmware symlinks
seed_configs/ # emulator INI settings, wrappers
scripts_in_box/ # deploy Python helpers into box
install_dlcs/ # PS3 PKG + Switch NSP batch install
switch_cheats/ # symlink cheats into Eden load path
rpcs3_per_game_configs/ # per-title RPCS3 tuning from API
retroarch_extras/ # 21 buildbot cores + 8 asset packs
pcsx2_textures/ # PCSX2 HD textures + per-game settings + .pnach patches
desktop_apps/ # .desktop entry rendering
configure_esde/ # ES-DE custom systems XML
shell_config/ # minimal zsh + starship
verify/ # post-setup assertions
refresh_shadps4/ # shadPS4 GitHub release management
install_xenia/ # Wine prefix and Xenia Manager
install_hedgemodmanager/ # native HMM 8 source build
install_pc_racing/ # Wine wrappers for tested Windows racing games
install_sonic_p06/ # Wine wrapper for Sonic Project '06
install_unleashed_recomp/ # native Unleashed Recompiled Flatpak install
ogm_catalog/ # host-side ogm (omarchy-games-menu) catalog fragment
scripts/ # helper scripts invoked by the Ansible roles
config/ # live config source trees (emulator INIs, ES-DE, desktop templates)
docs/ # historical notes and focused docs
#Documentation
Core setup & rebuild:
-
Sources & downloads — upstream repos/pages for every native port, recomp, decomp, fan game and ROM-hack tool, if you want to grab a build yourself
-
Save backups — mirror emulator/PC-port saves to the NAS (
backup-saves) and restore them on a fresh remount (restore-saves) -
Rebuild Runbook — from-scratch rebuild, opt-in tags, standalone playbooks
-
External Installers — download inventory for the opt-in Windows/Wine games and tools
-
ogm launcher integration — omarchy-games-menu catalog fragment,
ogm scanhooks -
Unsupported / parked games — games/mods we couldn't get working; the detailed trail lives in GitHub issues
-
Forza database editing — edit FM4/FM2 car prices & economy in gamedb.slt; swap PFP career/easy (Sandbox) modes; revert
-
Atari ST / Hatari — focused installation, BIOS setup and mandatory validation
Mods, patches & HD textures:
- NexusMods mod sets — authoritative inventory of the per-game
install_<game>_modsroles, shared loaders, GUI-tool/deferred items, and Proton gotchas - ROM-hack patching (xdelta/IPS) · GameCube NKIT→redump recovery
- HD texture packs (Dolphin/Azahar, NAS-symlinked)
- Metal Gear Master Collection fixes
- RE4 HD Project · FFVII 7th Heaven · GTA IV mods
- Cheats and trainers · Mario Maker levels
Windows / Wine games:
- PC Racing Games — Colin McRae Rally, OutRun 2006, Sega Rally, DiRT
- Driveclub shadPS4 — working v1.00 recipe, all dead ends captured
- GT5 Master Mod · Project Forza Plus (FM2/3/4/FH1 on Xenia)
- Sonic Project '06 · Hedge Mod Manager · Dusk / Twilight Princess
Arcade & ray-traced ports:
Xbox 360 & per-game tuning:
- Xenia Manager · Xbox 360 Title Updates · Xbox 360 PGR3 / PGR4
- GT2 (DuckStation) · GT3 (PCSX2) · GT4 Spec II (PCSX2) · GT5/GT6 (RPCS3)
- PS3 library · Azahar 3DS · PS1 60 FPS patches
Historical notes:
#Safety Rules
This repo does not provide ROMs, BIOS files, firmware, keys, or game packages.
Playbooks only detect, link, and configure files that already exist on your machine. They should not delete ROMs, BIOS, saves, firmware, or game data.
Generated emulator state, shader caches, saves, logs, firmware modules, and ROMs must not be committed.