279 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<meta name="theme-color" content="#FF8E03">
<meta property="og:title" content="Game Modding &middot; Citra" />
<meta property="og:site_name" content="Citra" />
<meta property="og:url" content="https://citra-emu.org/help/feature/game-modding/" />
<meta property="og:description" content="Citra has a powerful modding framework allowing for multiple formats of patches and flexibility in distribution." />
<meta name="description" content="Citra has a powerful modding framework allowing for multiple formats of patches and flexibility in distribution." />
<meta property="og:type" content="website" />
<link rel="icon" href="https://citra-emu.org/favicon.ico" />
<link rel="shortcut icon" href="https://citra-emu.org/favicon.ico" type="image/x-icon" />
<link rel="canonical" href="https://citra-emu.org/help/feature/game-modding/">
<title>Game Modding - Citra</title>
<link href="https://fonts.googleapis.com/css?family=Ubuntu|Dosis" rel="stylesheet">
<link rel="stylesheet" href="https://citra-emu.org/scss/style.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-73966905-1', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<nav class="navbar navbar-default navbar-wrapper navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">&nbsp;</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="index-1 first"><a href="/" title="Blog Posts">Blog</a></li>
<li class="index-2"><a href="/download/" title="Download Citra">Download</a></li>
<li class="index-3"><a href="/help/" title="Help">Help</a></li>
<li class="index-4"><a href="/wiki/faq/" title="Frequently Asked Questions">FAQ</a></li>
<li class="index-5"><a href="/game/" title="Game Compatibility">Compatibility</a></li>
<li class="index-6"><a href="/wiki/home/" title="Wiki Homepage">Wiki</a></li>
<li class="index-7 dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="false">
Social <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li class="index-1 first"><a href="/rules/" title="Community Rules">Rules</a></li>
<li class="index-2"><a href="https://community.citra-emu.org/" title="Forums">Community Forums</a></li>
<li class="index-3 last"><a href="/discord/" title="Discord Server">Discord Chat</a></li>
</ul>
</li>
<li class="index-8 dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">
Media <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li class="index-1 first"><a href="/screenshots/" title="Screenshots">Screenshots</a></li>
<li class="index-2 last"><a href="https://www.youtube.com/channel/UC_dcdgzuapBtAY4ol3x-90Q"
title="YouTube Channel">Videos</a></li>
</ul>
</li>
<li class="index-9 last"><a href="https://www.patreon.com/citraemu" title="Patreon">Patreon</a></li>
</ul>
</div>
</div>
</nav>
<div id="mainContainer" class="container" >
<div class="row">
</div>
<div class="row row-fluid">
<div id="content" class="col-xs-12 col-sm-12 col-md-9 col-lg-9 pull-right">
<h1>
Game Modding
</h1>
<div class="entry-content">
<p>Citra has a powerful modding framework allowing for multiple formats of patches and flexibility in distribution.</p>
<h3 id="directory-structure">Directory Structure</h3>
<p>The following is an example of a mod in Citra.<br>
Each title has its own Mods directory that can be opened by right-clicking on the game in Citra (alternatively <code>load/mods/&lt;Title ID&gt;</code> in the User Directory)</p>
<pre tabindex="0"><code>load/mods/&lt;Title ID&gt;
- exefs
- romfs
- romfs_ext
- exheader.bin
</code></pre><p>Note that everything demonstrated above is optional. It is possible that a mod contains only some of these files.</p>
<h4 id="exefs">ExeFS</h4>
<p>The ExeFS directory contains replacements or patches for the game&rsquo;s executable.
These types of mods typically alter game behavior or logic.
Currently you can put a replacement file, or apply two types of patches: <code>IPS</code> and <code>BPS</code>.</p>
<p>To use a replacement file for the game code, put a file named <code>code.bin</code> in the ExeFS directory.</p>
<p>To use an <code>IPS</code> patch, put a file named <code>code.ips</code> in the ExeFS directory.
More details on the <code>IPS</code> format can be found on <a href="https://zerosoft.zophar.net/ips.php">ZeroSoft</a> and <a href="http://old.smwiki.net/wiki/IPS_file_format">SMWiki</a>.</p>
<p>To use a <code>BPS</code> patch, put a file named <code>code.bps</code> in the ExeFS directory.
More details on the <code>BPS</code> format can be found on <a href="https://byuu.org/projects/beat#bps">byuu</a>.</p>
<p><em>Note: For compatiblity with Luma3DS, you can also put these ExeFS replacements/patches directly in the mods folder instead of the <code>exefs</code> subfolder.</em></p>
<h4 id="romfs">RomFS</h4>
<p>The RomFS directory contains replacements for the game&rsquo;s assets and general files.
These types of mods typically alter a game&rsquo;s textures, text, fonts, sounds, or other graphical assets.
If this directory is not empty, Citra will combine the contents of it with the base game with files from this directory taking precedence over the base.
This technique is called LayeredFS.</p>
<pre tabindex="0"><code>It is important to note that for this to work properly, the directory structure of the game has to be mirrored in this directory.
</code></pre><p>It is much easier to get started with a RomFS mod than an ExeFS mod.
To dump a game&rsquo;s RomFS, right-click on the game and select <code>Dump RomFS</code>.
The dumped directory will be opened after the dump was completed, and can be found at <code>dump/romfs/&lt;Title ID&gt;</code> in the User Directory.</p>
<h4 id="romfs-extension-romfs_ext">RomFS Extension (romfs_ext)</h4>
<p>The RomFS Extension directory contains patches and stubs for RomFS files.
This allows modders to delete files within the RomFS if a file of the same name but the extension <code>.stub</code> is found at the same directory within <code>romfs_ext</code>.
Similarly, if a file with the same name but with extension <code>.ips</code> or <code>.bps</code> is found at the same directory within <code>romfs_ext</code>, the base game file will be patched with it.</p>
<pre tabindex="0"><code>It is important to note that currently patches require loading the entire file into the RAM.
Please do not use too many patches at the same time. This will likely be improved in the future.
</code></pre><h4 id="exheader">ExHeader</h4>
<p>The <code>exheader.bin</code> overrides the game&rsquo;s ExHeader, which specifies information like codeset info and system mode. By overriding the ExHeader, modders can allow more code to be added or more RAM to be used.</p>
<h3 id="example">Example</h3>
<p>For example, let&rsquo;s examine Pokemon Ultra Sun, a popular game for modding.</p>
<p>Since its Title ID is <code>00040000001B5000</code>, our mods for this game will go in <code>load/mods/00040000001B5000</code> in the User Directory.</p>
<p>Within this folder, there are <code>exefs</code>, <code>romfs</code>, and <code>romfs_ext</code> directories and the <code>exheader.bin</code> file provided by the author.
It is okay to omit one (or more) of them if the mod does not need to replace those files. Additionally, if a folder is empty Citra will ignore it.</p>
<h3 id="using-mods-intended-for-luma3ds">Using Mods Intended for Luma3DS</h3>
<p>Citra&rsquo;s game modding framework offers drop-in compatibility with Luma3DS mods.</p>
<p>Just put a Luma3DS mod (usually structured like the following example) into Citra&rsquo;s mod folder for the title, and it should directly work.</p>
<pre tabindex="0"><code>luma/titles/&lt;Title ID&gt;
- romfs
- other files and folders
- code.bin / code.ips
- exheader.bin
</code></pre><p>Note that everything demonstrated above is optional. It is possible that a mod contains only some of these files.</p>
<h3 id="using-3gx-plugins">Using 3GX plugins</h3>
<p>Citra can use 3GX plugins by using the same format that the Luma3DS 3GX plugin loader uses. Plugins can be placed in 2 locations:</p>
<pre tabindex="0"><code>- sdmc/luma/plugins/&lt;TITLEID&gt;/&lt;filename&gt;.3gx
To set a plugin for a specified game (higher priority).
- sdmc/luma/plugins/default.3gx
To set a plugin which would be loaded for all games (lower priority).
</code></pre><p>You can find the <code>sdmc</code> folder in Citra&rsquo;s <a href="https://citra-emu.org/wiki/user-directory/">User Directory</a>.
After placing your plugin in the correct location, you&rsquo;ll need to check the 3GX plugin <code>Enable 3GX plugin loader</code> option in Citra&rsquo;s System settings. The plugin(s) should now apply the next time you run your game.</p>
<h3 id="conclusion">Conclusion</h3>
<p>If you are a modder looking to distribute mods for Citra and have further questions or doubts, feel free to ask in our Discord.</p>
<p>If you are a user trying to install a mod for Citra and are having issues with it, first try asking the mod author for help. If it still doesn&rsquo;t work, feel free to ask in our Discord.</p>
</div>
</div>
<div id="sidebar" class="col-xs-12 col-sm-12 col-md-3 col-lg-3 pull-left">
<div id="advertisement" class = "ad">
<h3>Advertisement</h3>
<ins class="ad adsbygoogle"
style="display:block"
data-ad-client="ca-pub-4126545610079023"
data-ad-slot="4223809695"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>
<div class="tagcloud hidden-sm hidden-xs">
<h3>News Tag Cloud</h3>
<ul>
<li><a class="taxonomy-citra-release" href="/tags/citra-release">citra-release</a></li>
<li><a class="taxonomy-feature-update" href="/tags/feature-update">feature-update</a></li>
<li><a class="taxonomy-progress-report" href="/tags/progress-report">progress-report</a></li>
</ul>
</div>
<div id="twitter" class="hidden-sm hidden-xs">
<a class="twitter-timeline" data-tweet-limit="3" href="https://twitter.com/citraemu?ref_src=twsrc%5Etfw">Tweet Feed</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
</div>
</div>
</div>
<div id="footer" class="container">
<div class="row">
<div class="col-md-2">
<h1>Citra</h1>
<a href="/entry">Blog</a>
<a href="/download/">Downloads</a>
<a href="/screenshots/">Screenshots</a>
<a href="https://www.patreon.com/citraemu">Patreon</a>
<a href="/donate/">Donate</a>
</div>
<div class="col-md-2">
<h1>Documentation</h1>
<a href="/help/">Help Documents</a>
<a href="/game/">Compatibility</a>
<a href="/wiki/home/">Wiki</a>
<a href="/wiki/faq/">FAQ</a>
</div>
<div class="col-md-2">
<h1>Blog</h1>
<a href="/entry">News &amp; Articles</a>
<a href="https://citra-emu.org/index.xml">RSS 2.0</a>
</div>
<div class="col-md-2">
<h1>Social</h1>
<a href="https://www.youtube.com/channel/UC_dcdgzuapBtAY4ol3x-90Q">YouTube</a>
<a href="https://www.facebook.com/citra.emu">Facebook</a>
<a href="https://twitter.com/citraemu">Twitter</a>
<a href="https://community.citra-emu.org/">Forums</a>
<a href="/discord">Discord</a>
<a href="/chat">IRC</a>
</ul>
</div>
<div class="col-md-2">
<h1>Get Involved</h1>
<a href="https://github.com/citra-emu/citra">GitHub / Source</a>
<a href="https://github.com/citra-emu/citra/issues">Issues</a>
<a href="https://github.com/citra-emu/citra/pulls">Pull Requests</a>
</div>
</div>
<div id="footer-bottom">
<div id="footer-brand"></div>
<div id="footer-legal">Copyright © 2024 Citra Emulator Project</div>
</div>
</div>
<script src="https://citra-emu.org/js/script.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.css" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.10.0/baguetteBox.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded", function() {
baguetteBox.run('.is-img-preview');
});
</script>
</body>
</html>