Ryujinx supports mods, allowing you to apply various customizations and improvements to your games.
Mods in Ryujinx can range from simple texture changes and character skins to more complex gameplay alterations, difficulty adjustments, and even resolution or frame rate improvements.
Here’s how mods work in Ryujinx and how you can set them up.
Mods in Ryujinx are typically in the form of files that alter the game’s data or instructions. They are loaded into the emulator through specific file structures and directories that mimic the game’s data layout. The emulator then applies these modifications when running the game, allowing players to experience custom features or changes.
This pull request adds full support for mods on Ryujinx. It follows Atmosphere’s structure with some enhancements for host FS and emulator convenience.
// named file replacers [RECOMMENDED]
@mods/contents///romfs/* [loose files]
@mods/contents///exefs/* [loose files]
// named patches [RECOMMENDED]
@mods/exefs_patches//.ips|*.pchtxt
@mods/nro_patches //.ips|*.pchtxt
@mods/kip_patches //.ips
// named title-specific patches [ENHANCEMENT]
@mods/contents///exefs/.ips|*.pchtxt
// global replacers [COMPATIBILITY, with ams]
@mods/contents//romfs.bin
@mods/contents//exefs.nsp
@mods/contents//romfs/* [loose files]
@mods/contents//exefs/* [loose files]
exefs.nsp
is located for an Application, it is used instead of base ExeFS.sdk
.sdk.stub
.main.npdm
..ips
(Supports IPS and IPS32) and .pchtxt
(IPSwitch) patches.exefs_patches
as you don’t have to worry about Title IDs. The mod loader will select the applicable patches automatically.<nso_build_id>[.anything_you_want].ips
.pchtxt
extension and have an @nsobid-
header as the first line.nro_patches/
and kip_patches/
follow exefs_patches
. KIP patches, while searched, don’t apply yet (as KIPs aren’t used).RomFS mods are either loose files placed in romfs/ or inside a single container romfs.bin.
The files are replaced in a layered fashion. Loose files are prioritized over any files inside romfs.bin which in return, are prioritized over the files in the base RomFS of the Application (same as Atmosphere). See At a glance
As an aside, to create a romfs.bin file one can use hactoolnet. Just pass the romfs directory as input and it should create a storage file. Here’s an example invocation:
hactoolnet.exe -t romfsbuild --outfile romfs.bin mymod/romfs
Ryujinx
- bis
- games
...
+ mods
+ contents
+ 0100E95012348000 (My game name)
+ My combined mod
+ exefs
= 123456789ABCDEF...ips
= main.stub
+ romfs
= <*> [loose game files]
+ My resolution mod
- exefs
+ My romfs mod
- romfs
...
+ 01006a805678e000
= exefs.nsp
= romfs.bin
- 01006A585fF8E000-some-name-here
...
+ exefs_patches
+ my game patch
= 123456789ABCDEF...ips
= some-test-patch.pchtxt
- patch for another game
...
- nro_patches [same as exefs_patches]
- kip_patches [same as exefs_patches]
00:00:00.412 | Application LoadApplication: Loading as XCI.
00:00:00.449 | ModLoader QueryContentsDir: Searching mods for Title 0100E95012348000
00:00:00.451 | ModLoader QueryTitleDir: Found mod 'force-max-resolution' [E]
00:00:00.451 | ModLoader QueryTitleDir: Found mod 'hq-textures' [R]
00:00:00.452 | ModLoader QueryPatchDirs: Found NSO patch 'my-game-mod-no-outlines'
00:00:00.456 | ModLoader ApplyRomFsMods: Applying RomFS mods for Title 0100E95012348000
00:00:00.466 | ModLoader ApplyRomFsMods: Replaced 45 file(s) over 2 mod(s). Processing base storage...
00:00:00.715 | ModLoader ApplyRomFsMods: Building new RomFS...
00:00:00.737 | ModLoader ApplyRomFsMods: Using modded RomFS
00:00:01.273 | ModLoader ApplyProgramPatches: Matching IPSwitch patch '1.0.0.pchtxt' in 'force-max-resolution' bid=C2C016016115BE3D616281E67E59A7918DAFEDBB
00:00:01.274 | ModLoader Parse: IPSwitch: # Mandatory Comment
00:00:01.274 | ModLoader Parse: IPSwitch: print_values 0x7e767e <= 1F2003D5
00:00:01.317 | Ptc LoadExeFs: Detected exefs modifications. PPTC disabled.
00:00:01.319 | Ptc Initialize: Initializing Profiled Persistent Translation Cache (enabled: False).
IPS based on Atmosphere’s implementation.
IPSwitch, my own, from the readme description and some samples.
NRO Patching is untested with actual patches (couldn’t find any).
romfs.bin can be useful in cases where there’s a ton of files to patch. Currently when a romfs mod is loaded, all the files in it will have open handles until emulation has ended. To reduce this number to one, a single-file approach is useful. This also bypasses the OS’s filesystem routines and may reduce overhead.
While LayeredFS is more accurate, it was slow to build in my tests, so currently a single RomFs instance is maintained where files are added/replaced. We can revisit adding “true” LayeredFS at a later date. They don’t seem as useful for now. I’m open to suggestions.
Tangentially related to modding, there’s some under-the-hood changes:
Note: PPTC is automatically disabled when valid changes to exefs are detected (romfs mods are still ok). It’s possible for PPTC to work with mods, but the code changes currently required for a proper solution (changes to JIT and PTC) are beyond the scope of this PR.
Current warning message is shown in sample logs.
Locate the Game’s Mod Folder:
Download Mods:
Organize the Mod Files:
\ModName\exefs\...
(for code modifications)\ModName\romfs\...
(for data, textures, and sound mods)Enable/Disable Mods:
Launch the Game: