<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://sadocs.unreliable.network/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kell</id>
	<title>SA Docs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://sadocs.unreliable.network/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kell"/>
	<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/wiki/Special:Contributions/Kell"/>
	<updated>2026-05-01T15:19:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=368</id>
		<title>Creating Mods</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=368"/>
		<updated>2025-10-09T19:57:43Z</updated>

		<summary type="html">&lt;p&gt;Kell: Fix link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are many ways to modify Sonic Adventure DX and Sonic Adventure 2: Battle on PC using the Mod Loaders, from basic file editing to powerful code injection.&lt;br /&gt;
&lt;br /&gt;
The first step is to create your mod using the [[Mod Managers|Mod Manager]]. This will create a folder in which you will be able to put your modifications without affecting the original game files or executable.&lt;br /&gt;
&lt;br /&gt;
From there, you will be able to do:&lt;br /&gt;
&lt;br /&gt;
* [[File Replacement]]&lt;br /&gt;
* [[Texture Replacement]]&lt;br /&gt;
* [[Cheat Codes]]&lt;br /&gt;
* [[Creating a DLL Mod|Code Injection (DLL Mod)]]&lt;br /&gt;
* [[Mod Updates|Automatic Updates]]&lt;br /&gt;
* [[Mod Configuration]]&lt;br /&gt;
&lt;br /&gt;
= Creating a mod =&lt;br /&gt;
To create a mod you need the SA Mod Manager with Sonic Adventure DX and/or Sonic Adventure 2: Battle set up.&lt;br /&gt;
&lt;br /&gt;
First open SA Mod Manager with the game of your choice and click on the &amp;quot;Add Mod&amp;quot; button in the Mods tab.&lt;br /&gt;
[[File:Add-mod-button.png|none|509x509px]]&lt;br /&gt;
Then select &amp;quot;New Mod (For Developers)&amp;quot;&lt;br /&gt;
[[File:Add-mod-prompt.png|none|500x500px]]&lt;br /&gt;
This opens the mod creation form.&lt;br /&gt;
&lt;br /&gt;
=== Mod Information ===&lt;br /&gt;
[[File:New-mod-form-info.png|none|600x600px]]&lt;br /&gt;
Here are the information requested (* is mandatory):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: the name of the mod&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: your nickname, it is acceptable to add co-authors separated with commas&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: short description of the mod, it appears below the mod list&lt;br /&gt;
* &#039;&#039;&#039;Version&#039;&#039;&#039;: a version number, preferably numbers and dots. A common way to represent version is &amp;quot;major.minor&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;DLL&#039;&#039;&#039;: for code injection, this is the name of the DLL with the extension (e.g. &amp;quot;my-mod.dll&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039;: one of the categories listed or none&lt;br /&gt;
* &#039;&#039;&#039;Mod ID*&#039;&#039;&#039;: a unique name for your mod that should not change, preferably without spaces (e.g. &amp;quot;game.author.modname&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Include Directories&#039;&#039;&#039;: this is used for codeless mod configuration&lt;br /&gt;
* &#039;&#039;&#039;Author URL&#039;&#039;&#039;: link to a page of your choice, ideally showcasing your mods (GameBanana or GitHub profile for example)&lt;br /&gt;
* &#039;&#039;&#039;Source Code URL&#039;&#039;&#039;: for code injection, link to the source code (GitHub repository for example)&lt;br /&gt;
&lt;br /&gt;
This should have created a folder with a system folder (for SADX) or a gd_PC folder (for SA2B), you can use these for [[file replacement]].&lt;br /&gt;
&lt;br /&gt;
=== Update information ===&lt;br /&gt;
[[File:New-mod-form-update.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Mod Updates|automatic updates]], it is generally filled out later.&lt;br /&gt;
&lt;br /&gt;
For GitHub:&lt;br /&gt;
&lt;br /&gt;
* Author and repo is the right part of the repository URL (e.g. myself/my-mod)&lt;br /&gt;
* Release Asset is the name of the zip file in the release (e.g. my-mod.7z)&lt;br /&gt;
&lt;br /&gt;
For GameBanana:&lt;br /&gt;
&lt;br /&gt;
* Mod ID is the number in the mod&#039;s page URL (e.g. 123456)&lt;br /&gt;
* Mod Type shouldn&#039;t be changed (legacy)&lt;br /&gt;
&lt;br /&gt;
For self hosted:&lt;br /&gt;
&lt;br /&gt;
* Update URL: path to mod folder root on a remote http server&lt;br /&gt;
* Changelog URL: path to changelog file (plain text)&lt;br /&gt;
&lt;br /&gt;
=== Cheat codes ===&lt;br /&gt;
[[File:New-mod-form-cheat.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Cheat Codes|cheat codes]].&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
[[File:New-mod-form-dependencies.png|none|600x600px]]&lt;br /&gt;
This tab is for mod dependencies. If your mod absolutely relies on another mod to function properly, you should add it here. The mod manager will warn users if they lack a dependency.&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Mod_Updates&amp;diff=367</id>
		<title>Mod Updates</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Mod_Updates&amp;diff=367"/>
		<updated>2025-10-09T19:56:20Z</updated>

		<summary type="html">&lt;p&gt;Kell: Initial draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[SA Mod Manager|Mod Manager]] allows you to set up automatic updates for your mod.&lt;br /&gt;
&lt;br /&gt;
There are currently 3 supported services:&lt;br /&gt;
&lt;br /&gt;
* Self-Hosted&lt;br /&gt;
* GitHub&lt;br /&gt;
* GameBanana&lt;br /&gt;
&lt;br /&gt;
== Configuring automatic updates ==&lt;br /&gt;
To configure automatic updates, open the Mod Manager, right click your mod and select &amp;quot;Edit Mod&amp;quot; (or select the mod and press Ctrl+E)&lt;br /&gt;
[[File:Samm-edit-mode-context-menu.png|none|302x302px]]&lt;br /&gt;
In the edit mode window, click on the &amp;quot;Update Info&amp;quot; tab.&lt;br /&gt;
[[File:Samm-editmod-updateinfo.png|none|428x428px]]&lt;br /&gt;
Now choose the service of your choice.&lt;br /&gt;
&lt;br /&gt;
=== GitHub ===&lt;br /&gt;
If the code of your mod is open source, you can release updates on your repository page.&lt;br /&gt;
&lt;br /&gt;
* Author and repo is the right part of the repository URL (e.g. myself/my-mod)&lt;br /&gt;
* Release Asset is the name of the zip file in the release (e.g. my-mod.7z)&lt;br /&gt;
&lt;br /&gt;
=== GameBanana ===&lt;br /&gt;
If you have your mod on GameBanana, you can release updates there.&lt;br /&gt;
&lt;br /&gt;
* Mod ID is the number in the mod&#039;s page URL (e.g. 123456)&lt;br /&gt;
* Mod Type shouldn&#039;t be changed (legacy)&lt;br /&gt;
&lt;br /&gt;
=== Self-Hosted ===&lt;br /&gt;
If none of the above, you can host the mod yourself on an HTTP server.&lt;br /&gt;
&lt;br /&gt;
* Update URL: path to mod folder root on a remote http server&lt;br /&gt;
* Changelog URL: path to changelog file (plain text)&lt;br /&gt;
&lt;br /&gt;
== Releasing an update ==&lt;br /&gt;
Before releasing an update, you need to &#039;&#039;&#039;update the manifest&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The manifest tells the Mod Manager which files need to be changed.&lt;br /&gt;
&lt;br /&gt;
For the first time, you need to enable the developer options of the Mod Manager. Go to the &amp;quot;Manager Config&amp;quot; tab and check the &amp;quot;Enable Developer Options&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
1. Right click your mod, then select &amp;quot;Developer&amp;quot; &amp;gt;&amp;quot;Generate Manifest&amp;quot;&lt;br /&gt;
[[File:Samm-modcontext-generatemanifest.png|none|500x500px]]&lt;br /&gt;
2. If you have modified something, the Manifest Generator window will pop up showing what&#039;s changed.&lt;br /&gt;
[[File:Samm-manifest-generator.png|none|400x400px]]&lt;br /&gt;
(If some of these files won&#039;t be in the released zip, uncheck them. By default the Mod Manager automatically ignores config.ini)&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;OK&amp;quot;, you may now release the update.&lt;br /&gt;
&lt;br /&gt;
{{Note|text=If you have already released your mod and are adding automatic updates now, it won&#039;t work until users update it manually once.|type=warn}}&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-manifest-generator.png&amp;diff=366</id>
		<title>File:Samm-manifest-generator.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-manifest-generator.png&amp;diff=366"/>
		<updated>2025-10-09T19:47:51Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-modcontext-generatemanifest.png&amp;diff=365</id>
		<title>File:Samm-modcontext-generatemanifest.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-modcontext-generatemanifest.png&amp;diff=365"/>
		<updated>2025-10-09T19:45:51Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-editmod-updateinfo.png&amp;diff=364</id>
		<title>File:Samm-editmod-updateinfo.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-editmod-updateinfo.png&amp;diff=364"/>
		<updated>2025-10-09T19:24:07Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=360</id>
		<title>Creating Mods/Creating a DLL Mod</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=360"/>
		<updated>2025-10-08T22:06:24Z</updated>

		<summary type="html">&lt;p&gt;Kell: Discord links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to have more control over the game, you can compile a C++ DLL to modify or call the game&#039;s own code easily. This tutorial will go through the most basic method to get a DLL running.&lt;br /&gt;
&lt;br /&gt;
Note that if you just want to replace assets or change level geometry for example, you do not need a DLL.&lt;br /&gt;
&lt;br /&gt;
== 1. Prerequisites ==&lt;br /&gt;
In order to build DLL files, you will need Visual Studio Community with C++ capabilities. You can download the Visual Studio Installer [https://visualstudio.microsoft.com/fr/downloads/ here]. &lt;br /&gt;
&lt;br /&gt;
Open the installer, choose Visual Studio Community, then &amp;quot;Desktop Development with C++&amp;quot; and wait until the installation is finished.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You only need the toolkit (the latest is v143), the SDK and the debugger.&#039;&#039;&lt;br /&gt;
[[File:Visual-studio-installer.gif|none|646x646px]]&lt;br /&gt;
&lt;br /&gt;
== 2. Creating a DLL project ==&lt;br /&gt;
Now that Visual Studio is installed, we need to make a C++ DLL project.&lt;br /&gt;
&lt;br /&gt;
1. Click on &amp;quot;Create a new project&amp;quot; on the starting page. If there&#039;s no starting page, click on &amp;quot;File&amp;quot; then &amp;quot;New project&amp;quot;.&lt;br /&gt;
[[File:Visual-studio-launcher.png|none|600x600px]]&lt;br /&gt;
2. Select the Dynamic Link Library (DLL) template&lt;br /&gt;
[[File:Visual-studio-launcher-template.png|none|600x600px]]&lt;br /&gt;
3. Choose a name and a location for your project.&lt;br /&gt;
[[File:Visual-studio-launcher-createproject.png|none|600x600px]]&lt;br /&gt;
Navigate to the location you&#039;ve chosen for the project. Visual Studio has created several project files.&lt;br /&gt;
&lt;br /&gt;
* The folder where the &amp;lt;code&amp;gt;.sln&amp;lt;/code&amp;gt; file is located is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;solution&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
* The subfolder containing the &amp;lt;code&amp;gt;.vcxproj&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;project&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
The &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files are files containing C or C++ code, they will be compiled into machine code inside the DLL. The &amp;lt;code&amp;gt;.h&amp;lt;/code&amp;gt; files are header files, they contain information that cpp files can use.&lt;br /&gt;
&lt;br /&gt;
== 3. Add the Mod Loader headers ==&lt;br /&gt;
We already have enough to build a DLL, but we do not have modding capabilities yet. For that, we need to add the Mod Loader headers.&lt;br /&gt;
&lt;br /&gt;
1. Go on the GitHub page of the [https://github.com/X-Hax/sadx-mod-loader SADX Mod Loader] or the [https://github.com/X-Hax/sa2-mod-loader SA2 Mod Loader].&lt;br /&gt;
&lt;br /&gt;
2. Download the repository by clicking on the green &amp;quot;&amp;lt; &amp;gt; Code&amp;quot; button then &amp;quot;Download ZIP&amp;quot;.&lt;br /&gt;
[[File:Github-download-repo.png|none|296x296px]]&lt;br /&gt;
3. Move the content of SADXModLoader/include (or SA2ModLoader/include) into your &#039;&#039;&#039;project&#039;&#039;&#039; folder.&lt;br /&gt;
[[File:Dll-mod-project-folder-example-sadx.png|none|502x502px]]&lt;br /&gt;
These files provide modding capabilities to your project, we will learn how to actually use them later on.&lt;br /&gt;
&lt;br /&gt;
== 4. Creating a source file ==&lt;br /&gt;
Now we need a space to start coding, we will create a new source (.cpp) file where we will put our own code.&lt;br /&gt;
&lt;br /&gt;
1. In Visual Studio, right click &amp;quot;Source Files&amp;quot; then click Add -&amp;gt; New Item...&lt;br /&gt;
[[File:Visual-studio-add-new-item.png|none|450x450px]]&lt;br /&gt;
2. Name it however you want, for example mod.cpp&lt;br /&gt;
[[File:Visual-studio-add-new-item-form-cpp.png|none|450x450px]]&lt;br /&gt;
3. Now we have our own space where we can start coding.&lt;br /&gt;
&lt;br /&gt;
The first line should be:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;pch.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;If you&#039;re new to C++ development, you will learn what this is used for later.&lt;br /&gt;
&lt;br /&gt;
After that, we need to include the Mod Loader headers with the following line:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SADXModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SA2ModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Adding the entry points ==&lt;br /&gt;
Now we need to add entry points to our DLL for the Mod Loader. In order for the Mod Loader to see our entry points, we need to use DLL exports. A DLL export allows other programs to use things from our DLL.&lt;br /&gt;
&lt;br /&gt;
First we add the &#039;&#039;&#039;ModInfo&#039;&#039;&#039; export, this tells the Mod Loader that our DLL is a valid mod.&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer };&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SA2ModInfo = { ModLoaderVer };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Now we can add the most important entry point, the Init function:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl Init(const char* path, const HelperFunctions&amp;amp; helperFunctions)&lt;br /&gt;
{&lt;br /&gt;
	// Executed at startup, contains helperFunctions and the path to your mod folder&lt;br /&gt;
	// This is where we initialize things, override functions, replace static data, etc.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;And a bunch of other optional exports:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnFrame()&lt;br /&gt;
{&lt;br /&gt;
	// Executed every running frame of SADX&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnInput()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnControl()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceReset()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the window size changes&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceLost()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game fails to render the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneStart()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game starts rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneEnd()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game finishes rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnExit()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game is about to terminate&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Here is what your source file should more or less look like:&lt;br /&gt;
[[File:Mod-example-dllexports.png|none|604x604px]]&lt;br /&gt;
&lt;br /&gt;
== 6. Building the DLL ==&lt;br /&gt;
Our project is ready, we can now build the mod.&lt;br /&gt;
&lt;br /&gt;
First, make sure you are building for the x86 (32bit) architecture, you can select it at the top.&lt;br /&gt;
[[File:Vs-build-mode.png|none|360x360px]]&lt;br /&gt;
Currently, it is building in the &amp;quot;&#039;&#039;&#039;Debug&#039;&#039;&#039;&amp;quot; configuration. This mode is useful for [[debugging]] and should only be used while testing your mod. Once you want to release it to the world, you should change it to the &amp;quot;&#039;&#039;&#039;Release&#039;&#039;&#039;&amp;quot; configuration and rebuild.&lt;br /&gt;
&lt;br /&gt;
Now press Ctrl+B or click &amp;quot;Build&amp;quot; in the top panel -&amp;gt; &amp;quot;Build Solution&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The DLL should now build. If you get errors, make sure you haven&#039;t missed a step and try to understand their meaning. If you are stuck, you should come on our [https://discord.gg/gqJCF47 Discord server] for help.&lt;br /&gt;
&lt;br /&gt;
== 7. Testing the mod ==&lt;br /&gt;
Our DLL was generated in the solution folder, inside a &amp;quot;Debug&amp;quot; or &amp;quot;Release&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
1. Copy the DLL into your mod folder.&lt;br /&gt;
&lt;br /&gt;
2. If you have not already, you need to edit the mod in the Mod Manager to add the name of your dll.&lt;br /&gt;
[[File:Samm-edit-mode-context-menu.png|none|302x302px]]&lt;br /&gt;
[[File:Samm-edit-mod-dllname.png|none|600x600px]]&lt;br /&gt;
3. Now you can launch the game, make sure the mod is enabled.&lt;br /&gt;
&lt;br /&gt;
If nothing happens, it&#039;s probably working! If an error shows up, try to understand it or ask us for directions on [https://discord.gg/gqJCF47 Discord].&lt;br /&gt;
&lt;br /&gt;
== 8. Doing something ==&lt;br /&gt;
The problem is that our DLL does nothing for now.&lt;br /&gt;
&lt;br /&gt;
This is where you should start experimenting:&lt;br /&gt;
&lt;br /&gt;
* If you are new to C++ development, see [[General Programming Guide]].&lt;br /&gt;
* Open the Mod Loader headers to see what they contain, specifically the Variables and Functions ones.&lt;br /&gt;
* If you are already experimented, take a look at the community driven [[Working with the Disassembly|disassembly]].&lt;br /&gt;
* Take a look at open source SADX/SA2 mods on GitHub to learn from them.&lt;br /&gt;
&lt;br /&gt;
If you want to quickly check if it&#039;s working, try to add &amp;lt;code&amp;gt;Rings = 999;&amp;lt;/code&amp;gt; in the OnFrame entry point, this is the ingame ring counter.&lt;br /&gt;
&lt;br /&gt;
If you have enabled the Debug Console in the Mod Manager options, you can print to it with:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
PrintDebug(&amp;quot;text\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;After any modification, you need to rebuild the DLL, and move it to the mod folder again.&lt;br /&gt;
&lt;br /&gt;
Once you are familiar enough with the process, you can make your life easier with [[debugging]].&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=359</id>
		<title>Creating Mods/Creating a DLL Mod</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=359"/>
		<updated>2025-10-08T21:52:21Z</updated>

		<summary type="html">&lt;p&gt;Kell: Typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to have more control over the game, you can compile a C++ DLL to modify or call the game&#039;s own code easily. This tutorial will go through the most basic method to get a DLL running.&lt;br /&gt;
&lt;br /&gt;
Note that if you just want to replace assets or change level geometry for example, you do not need a DLL.&lt;br /&gt;
&lt;br /&gt;
== 1. Prerequisites ==&lt;br /&gt;
In order to build DLL files, you will need Visual Studio Community with C++ capabilities. You can download the Visual Studio Installer [https://visualstudio.microsoft.com/fr/downloads/ here]. &lt;br /&gt;
&lt;br /&gt;
Open the installer, choose Visual Studio Community, then &amp;quot;Desktop Development with C++&amp;quot; and wait until the installation is finished.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You only need the toolkit (the latest is v143), the SDK and the debugger.&#039;&#039;&lt;br /&gt;
[[File:Visual-studio-installer.gif|none|646x646px]]&lt;br /&gt;
&lt;br /&gt;
== 2. Creating a DLL project ==&lt;br /&gt;
Now that Visual Studio is installed, we need to make a C++ DLL project.&lt;br /&gt;
&lt;br /&gt;
1. Click on &amp;quot;Create a new project&amp;quot; on the starting page. If there&#039;s no starting page, click on &amp;quot;File&amp;quot; then &amp;quot;New project&amp;quot;.&lt;br /&gt;
[[File:Visual-studio-launcher.png|none|600x600px]]&lt;br /&gt;
2. Select the Dynamic Link Library (DLL) template&lt;br /&gt;
[[File:Visual-studio-launcher-template.png|none|600x600px]]&lt;br /&gt;
3. Choose a name and a location for your project.&lt;br /&gt;
[[File:Visual-studio-launcher-createproject.png|none|600x600px]]&lt;br /&gt;
Navigate to the location you&#039;ve chosen for the project. Visual Studio has created several project files.&lt;br /&gt;
&lt;br /&gt;
* The folder where the &amp;lt;code&amp;gt;.sln&amp;lt;/code&amp;gt; file is located is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;solution&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
* The subfolder containing the &amp;lt;code&amp;gt;.vcxproj&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;project&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
The &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files are files containing C or C++ code, they will be compiled into machine code inside the DLL. The &amp;lt;code&amp;gt;.h&amp;lt;/code&amp;gt; files are header files, they contain information that cpp files can use.&lt;br /&gt;
&lt;br /&gt;
== 3. Add the Mod Loader headers ==&lt;br /&gt;
We already have enough to build a DLL, but we do not have modding capabilities yet. For that, we need to add the Mod Loader headers.&lt;br /&gt;
&lt;br /&gt;
1. Go on the GitHub page of the [https://github.com/X-Hax/sadx-mod-loader SADX Mod Loader] or the [https://github.com/X-Hax/sa2-mod-loader SA2 Mod Loader].&lt;br /&gt;
&lt;br /&gt;
2. Download the repository by clicking on the green &amp;quot;&amp;lt; &amp;gt; Code&amp;quot; button then &amp;quot;Download ZIP&amp;quot;.&lt;br /&gt;
[[File:Github-download-repo.png|none|296x296px]]&lt;br /&gt;
3. Move the content of SADXModLoader/include (or SA2ModLoader/include) into your &#039;&#039;&#039;project&#039;&#039;&#039; folder.&lt;br /&gt;
[[File:Dll-mod-project-folder-example-sadx.png|none|502x502px]]&lt;br /&gt;
These files provide modding capabilities to your project, we will learn how to actually use them later on.&lt;br /&gt;
&lt;br /&gt;
== 4. Creating a source file ==&lt;br /&gt;
Now we need a space to start coding, we will create a new source (.cpp) file where we will put our own code.&lt;br /&gt;
&lt;br /&gt;
1. In Visual Studio, right click &amp;quot;Source Files&amp;quot; then click Add -&amp;gt; New Item...&lt;br /&gt;
[[File:Visual-studio-add-new-item.png|none|450x450px]]&lt;br /&gt;
2. Name it however you want, for example mod.cpp&lt;br /&gt;
[[File:Visual-studio-add-new-item-form-cpp.png|none|450x450px]]&lt;br /&gt;
3. Now we have our own space where we can start coding.&lt;br /&gt;
&lt;br /&gt;
The first line should be:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;pch.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;If you&#039;re new to C++ development, you will learn what this is used for later.&lt;br /&gt;
&lt;br /&gt;
After that, we need to include the Mod Loader headers with the following line:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SADXModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SA2ModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Adding the entry points ==&lt;br /&gt;
Now we need to add entry points to our DLL for the Mod Loader. In order for the Mod Loader to see our entry points, we need to use DLL exports. A DLL export allows other programs to use things from our DLL.&lt;br /&gt;
&lt;br /&gt;
First we add the &#039;&#039;&#039;ModInfo&#039;&#039;&#039; export, this tells the Mod Loader that our DLL is a valid mod.&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer };&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SA2ModInfo = { ModLoaderVer };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Now we can add the most important entry point, the Init function:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl Init(const char* path, const HelperFunctions&amp;amp; helperFunctions)&lt;br /&gt;
{&lt;br /&gt;
	// Executed at startup, contains helperFunctions and the path to your mod folder&lt;br /&gt;
	// This is where we initialize things, override functions, replace static data, etc.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;And a bunch of other optional exports:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnFrame()&lt;br /&gt;
{&lt;br /&gt;
	// Executed every running frame of SADX&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnInput()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnControl()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceReset()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the window size changes&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceLost()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game fails to render the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneStart()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game starts rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneEnd()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game finishes rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnExit()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game is about to terminate&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Here is what your source file should more or less look like:&lt;br /&gt;
[[File:Mod-example-dllexports.png|none|604x604px]]&lt;br /&gt;
&lt;br /&gt;
== 6. Building the DLL ==&lt;br /&gt;
Our project is ready, we can now build the mod.&lt;br /&gt;
&lt;br /&gt;
First, make sure you are building for the x86 (32bit) architecture, you can select it at the top.&lt;br /&gt;
[[File:Vs-build-mode.png|none|360x360px]]&lt;br /&gt;
Currently, it is building in the &amp;quot;&#039;&#039;&#039;Debug&#039;&#039;&#039;&amp;quot; configuration. This mode is useful for [[debugging]] and should only be used while testing your mod. Once you want to release it to the world, you should change it to the &amp;quot;&#039;&#039;&#039;Release&#039;&#039;&#039;&amp;quot; configuration and rebuild.&lt;br /&gt;
&lt;br /&gt;
Now press Ctrl+B or click &amp;quot;Build&amp;quot; in the top panel -&amp;gt; &amp;quot;Build Solution&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The DLL should now build. If you get errors, make sure you haven&#039;t missed a step and try to understand their meaning. If you are stuck, you should come on our Discord server for help.&lt;br /&gt;
&lt;br /&gt;
== 7. Testing the mod ==&lt;br /&gt;
Our DLL was generated in the solution folder, inside a &amp;quot;Debug&amp;quot; or &amp;quot;Release&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
1. Copy the DLL into your mod folder.&lt;br /&gt;
&lt;br /&gt;
2. If you have not already, you need to edit the mod in the Mod Manager to add the name of your dll.&lt;br /&gt;
[[File:Samm-edit-mode-context-menu.png|none|302x302px]]&lt;br /&gt;
[[File:Samm-edit-mod-dllname.png|none|600x600px]]&lt;br /&gt;
3. Now you can launch the game, make sure the mod is enabled.&lt;br /&gt;
&lt;br /&gt;
If nothing happens, it&#039;s probably working! If an error shows up, try to understand it or ask us for directions on Discord.&lt;br /&gt;
&lt;br /&gt;
== 8. Doing something ==&lt;br /&gt;
The problem is that our DLL does nothing for now.&lt;br /&gt;
&lt;br /&gt;
This is where you should start experimenting:&lt;br /&gt;
&lt;br /&gt;
* If you are new to C++ development, see [[General Programming Guide]].&lt;br /&gt;
* Open the Mod Loader headers to see what they contain, specifically the Variables and Functions ones.&lt;br /&gt;
* If you are already experimented, take a look at the community driven [[Working with the Disassembly|disassembly]].&lt;br /&gt;
* Take a look at open source SADX/SA2 mods on GitHub to learn from them.&lt;br /&gt;
&lt;br /&gt;
If you want to quickly check if it&#039;s working, try to add &amp;lt;code&amp;gt;Rings = 999;&amp;lt;/code&amp;gt; in the OnFrame entry point, this is the ingame ring counter.&lt;br /&gt;
&lt;br /&gt;
If you have enabled the Debug Console in the Mod Manager options, you can print to it with:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
PrintDebug(&amp;quot;text\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;After any modification, you need to rebuild the DLL, and move it to the mod folder again.&lt;br /&gt;
&lt;br /&gt;
Once you are familiar enough with the process, you can make your life easier with [[debugging]].&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=358</id>
		<title>Creating Mods</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=358"/>
		<updated>2025-10-08T21:50:11Z</updated>

		<summary type="html">&lt;p&gt;Kell: Edit links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are many ways to modify Sonic Adventure DX and Sonic Adventure 2: Battle on PC using the Mod Loaders, from basic file editing to powerful code injection.&lt;br /&gt;
&lt;br /&gt;
The first step is to create your mod using the [[Mod Managers|Mod Manager]]. This will create a folder in which you will be able to put your modifications without affecting the original game files or executable.&lt;br /&gt;
&lt;br /&gt;
From there, you will be able to do:&lt;br /&gt;
&lt;br /&gt;
* [[File Replacement]]&lt;br /&gt;
* [[Texture Replacement]]&lt;br /&gt;
* [[Cheat Codes]]&lt;br /&gt;
* [[Creating a DLL Mod|Code Injection (DLL Mod)]]&lt;br /&gt;
* [[Mod Updates|Automatic Updates]]&lt;br /&gt;
* [[Mod Configuration]]&lt;br /&gt;
&lt;br /&gt;
= Creating a mod =&lt;br /&gt;
To create a mod you need the SA Mod Manager with Sonic Adventure DX and/or Sonic Adventure 2: Battle set up.&lt;br /&gt;
&lt;br /&gt;
First open SA Mod Manager with the game of your choice and click on the &amp;quot;Add Mod&amp;quot; button in the Mods tab.&lt;br /&gt;
[[File:Add-mod-button.png|none|509x509px]]&lt;br /&gt;
Then select &amp;quot;New Mod (For Developers)&amp;quot;&lt;br /&gt;
[[File:Add-mod-prompt.png|none|500x500px]]&lt;br /&gt;
This opens the mod creation form.&lt;br /&gt;
&lt;br /&gt;
=== Mod Information ===&lt;br /&gt;
[[File:New-mod-form-info.png|none|600x600px]]&lt;br /&gt;
Here are the information requested (* is mandatory):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: the name of the mod&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: your nickname, it is acceptable to add co-authors separated with commas&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: short description of the mod, it appears below the mod list&lt;br /&gt;
* &#039;&#039;&#039;Version&#039;&#039;&#039;: a version number, preferably numbers and dots. A common way to represent version is &amp;quot;major.minor&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;DLL&#039;&#039;&#039;: for code injection, this is the name of the DLL with the extension (e.g. &amp;quot;my-mod.dll&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039;: one of the categories listed or none&lt;br /&gt;
* &#039;&#039;&#039;Mod ID*&#039;&#039;&#039;: a unique name for your mod that should not change, preferably without spaces (e.g. &amp;quot;game.author.modname&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Include Directories&#039;&#039;&#039;: this is used for codeless mod configuration&lt;br /&gt;
* &#039;&#039;&#039;Author URL&#039;&#039;&#039;: link to a page of your choice, ideally showcasing your mods (GameBanana or GitHub profile for example)&lt;br /&gt;
* &#039;&#039;&#039;Source Code URL&#039;&#039;&#039;: for code injection, link to the source code (GitHub repository for example)&lt;br /&gt;
&lt;br /&gt;
This should have created a folder with a system folder (for SADX) or a gd_PC folder (for SA2B), you can use these for [[file replacement]].&lt;br /&gt;
&lt;br /&gt;
=== Update information ===&lt;br /&gt;
[[File:New-mod-form-update.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Creating mods/Automatic updates|automatic updates]], it is generally filled out later.&lt;br /&gt;
&lt;br /&gt;
For GitHub:&lt;br /&gt;
&lt;br /&gt;
* Author and repo is the right part of the repository URL (e.g. myself/my-mod)&lt;br /&gt;
* Release Asset is the name of the zip file in the release (e.g. my-mod.7z)&lt;br /&gt;
&lt;br /&gt;
For GameBanana:&lt;br /&gt;
&lt;br /&gt;
* Mod ID is the number in the mod&#039;s page URL (e.g. 123456)&lt;br /&gt;
* Mod Type shouldn&#039;t be changed (legacy)&lt;br /&gt;
&lt;br /&gt;
For self hosted:&lt;br /&gt;
&lt;br /&gt;
* Update URL: path to mod folder root on a remote http server&lt;br /&gt;
* Changelog URL: path to changelog file (plain text)&lt;br /&gt;
&lt;br /&gt;
=== Cheat codes ===&lt;br /&gt;
[[File:New-mod-form-cheat.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Cheat Codes|cheat codes]].&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
[[File:New-mod-form-dependencies.png|none|600x600px]]&lt;br /&gt;
This tab is for mod dependencies. If your mod absolutely relies on another mod to function properly, you should add it here. The mod manager will warn users if they lack a dependency.&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=357</id>
		<title>Creating Mods/Creating a DLL Mod</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Creating_a_DLL_Mod&amp;diff=357"/>
		<updated>2025-10-08T21:47:57Z</updated>

		<summary type="html">&lt;p&gt;Kell: Initial draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to have more control over the game, you can compile a c++ DLL to modify or call the game&#039;s own code easily. This tutorial will go through the most basic method to get a DLL running.&lt;br /&gt;
&lt;br /&gt;
Note that if you just want to replace assets or change level geometry for example, you do not need a DLL.&lt;br /&gt;
&lt;br /&gt;
== 1. Prerequisites ==&lt;br /&gt;
In order to build DLL files, you will need Visual Studio Community with C++ capabilities. You can downloader the Visual Studio installer [https://visualstudio.microsoft.com/fr/downloads/ here]. &lt;br /&gt;
&lt;br /&gt;
Open the installer, choose Visual Studio Community, then &amp;quot;Desktop Development with C++&amp;quot; and wait until the installation is finished.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You only need the toolkit (the latest is v143), the SDK and the debugger.&#039;&#039;&lt;br /&gt;
[[File:Visual-studio-installer.gif|none|646x646px]]&lt;br /&gt;
&lt;br /&gt;
== 2. Creating a DLL project ==&lt;br /&gt;
Now that Visual Studio is installed, we need to make a C++ DLL project.&lt;br /&gt;
&lt;br /&gt;
1. Click on &amp;quot;Create a new project&amp;quot; on the starting page. If there&#039;s no starting page, click on &amp;quot;File&amp;quot; then &amp;quot;New project&amp;quot;.&lt;br /&gt;
[[File:Visual-studio-launcher.png|none|600x600px]]&lt;br /&gt;
2. Select the Dynamic Link Library (DLL) template&lt;br /&gt;
[[File:Visual-studio-launcher-template.png|none|600x600px]]&lt;br /&gt;
3. Choose a name and a location for your project.&lt;br /&gt;
[[File:Visual-studio-launcher-createproject.png|none|600x600px]]&lt;br /&gt;
Navigate to the location you&#039;ve chosen for the project. Visual Studio has created several project files.&lt;br /&gt;
&lt;br /&gt;
* The folder where the &amp;lt;code&amp;gt;.sln&amp;lt;/code&amp;gt; file is located is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;solution&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
* The subfolder containing the &amp;lt;code&amp;gt;.vcxproj&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files is called the &#039;&#039;&#039;&amp;lt;u&amp;gt;project&amp;lt;/u&amp;gt;&#039;&#039;&#039; folder.&lt;br /&gt;
The &amp;lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; files are files containing C or C++ code, they will be compiled into machine code inside the DLL. The &amp;lt;code&amp;gt;.h&amp;lt;/code&amp;gt; files are header files, they contain information that cpp files can use.&lt;br /&gt;
&lt;br /&gt;
== 3. Add the Mod Loader headers ==&lt;br /&gt;
We already have enough to build a DLL, but we do not have modding capabilities yet. For that, we need to add the Mod Loader headers.&lt;br /&gt;
&lt;br /&gt;
1. Go on the GitHub page of the [https://github.com/X-Hax/sadx-mod-loader SADX Mod Loader] or the [https://github.com/X-Hax/sa2-mod-loader SA2 Mod Loader].&lt;br /&gt;
&lt;br /&gt;
2. Download the repository by clicking on the green &amp;quot;&amp;lt; &amp;gt; Code&amp;quot; button then &amp;quot;Download ZIP&amp;quot;.&lt;br /&gt;
[[File:Github-download-repo.png|none|296x296px]]&lt;br /&gt;
3. Move the content of SADXModLoader/include (or SA2ModLoader/include) into your &#039;&#039;&#039;project&#039;&#039;&#039; folder.&lt;br /&gt;
[[File:Dll-mod-project-folder-example-sadx.png|none|502x502px]]&lt;br /&gt;
These files provide modding capabilities to your project, we will learn how to actually use them later on.&lt;br /&gt;
&lt;br /&gt;
== 4. Creating a source file ==&lt;br /&gt;
Now we need a space to start coding, we will create a new source (.cpp) file where we will put our own code.&lt;br /&gt;
&lt;br /&gt;
1. In Visual Studio, right click &amp;quot;Source Files&amp;quot; then click Add -&amp;gt; New Item...&lt;br /&gt;
[[File:Visual-studio-add-new-item.png|none|450x450px]]&lt;br /&gt;
2. Name it however you want, for example mod.cpp&lt;br /&gt;
[[File:Visual-studio-add-new-item-form-cpp.png|none|450x450px]]&lt;br /&gt;
3. Now we have our own space where we can start coding.&lt;br /&gt;
&lt;br /&gt;
The first line should be:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;pch.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;If you&#039;re new to C++ development, you will learn what this is used for later.&lt;br /&gt;
&lt;br /&gt;
After that, we need to include the Mod Loader headers with the following line:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SADXModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SA2ModLoader.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Adding the entry points ==&lt;br /&gt;
Now we need to add entry points to our DLL for the Mod Loader. In order for the Mod Loader to see our entry points, we need to use DLL exports. A DLL export allows other programs to use things from our DLL.&lt;br /&gt;
&lt;br /&gt;
First we add the &#039;&#039;&#039;ModInfo&#039;&#039;&#039; export, this tells the Mod Loader that our DLL is a valid mod.&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer };&amp;lt;/syntaxhighlight&amp;gt;OR&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) ModInfo SA2ModInfo = { ModLoaderVer };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Now we can add the most important entry point, the Init function:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl Init(const char* path, const HelperFunctions&amp;amp; helperFunctions)&lt;br /&gt;
{&lt;br /&gt;
	// Executed at startup, contains helperFunctions and the path to your mod folder&lt;br /&gt;
	// This is where we initialize things, override functions, replace static data, etc.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;And a bunch of other optional exports:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnFrame()&lt;br /&gt;
{&lt;br /&gt;
	// Executed every running frame of SADX&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnInput()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnControl()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game processes input&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceReset()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the window size changes&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderDeviceLost()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game fails to render the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneStart()&lt;br /&gt;
{&lt;br /&gt;
	// Executed before the game starts rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnRenderSceneEnd()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game finishes rendering the scene&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; __declspec(dllexport) void __cdecl OnExit()&lt;br /&gt;
{&lt;br /&gt;
	// Executed when the game is about to terminate&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Here is what your source file should more or less look like:&lt;br /&gt;
[[File:Mod-example-dllexports.png|none|604x604px]]&lt;br /&gt;
&lt;br /&gt;
== 6. Building the DLL ==&lt;br /&gt;
Our project is ready, we can now build the mod.&lt;br /&gt;
&lt;br /&gt;
First, make sure you are building for the x86 (32bit) architecture, you can select it at the top.&lt;br /&gt;
[[File:Vs-build-mode.png|none|360x360px]]&lt;br /&gt;
Currently, it is building in the &amp;quot;&#039;&#039;&#039;Debug&#039;&#039;&#039;&amp;quot; configuration. This mode is useful for [[debugging]] and should only be used while testing your mod. Once you want to release it to the world, you should change it to the &amp;quot;&#039;&#039;&#039;Release&#039;&#039;&#039;&amp;quot; configuration and rebuild.&lt;br /&gt;
&lt;br /&gt;
Now press Ctrl+B or click &amp;quot;Build&amp;quot; in the top panel -&amp;gt; &amp;quot;Build Solution&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The DLL should now build. If you get errors, make sure you haven&#039;t missed a step and try to understand their meaning. If you are stuck, you should come on our Discord server for help.&lt;br /&gt;
&lt;br /&gt;
== 7. Testing the mod ==&lt;br /&gt;
Our DLL was generated in the solution folder, inside a &amp;quot;Debug&amp;quot; or &amp;quot;Release&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
1. Copy the DLL into your mod folder.&lt;br /&gt;
&lt;br /&gt;
2. If you have not already, you need to edit the mod in the Mod Manager to add the name of your dll.&lt;br /&gt;
[[File:Samm-edit-mode-context-menu.png|none|302x302px]]&lt;br /&gt;
[[File:Samm-edit-mod-dllname.png|none|600x600px]]&lt;br /&gt;
3. Now you can launch the game, make sure the mod is enabled.&lt;br /&gt;
&lt;br /&gt;
If nothing happens, it&#039;s probably working! If an error shows up, try to understand it or ask us for directions on Discord.&lt;br /&gt;
&lt;br /&gt;
== 8. Doing something ==&lt;br /&gt;
The problem is that our DLL does nothing for now.&lt;br /&gt;
&lt;br /&gt;
This is where you should start experimenting:&lt;br /&gt;
&lt;br /&gt;
* If you are new to C++ development, see [[General Programming Guide]].&lt;br /&gt;
* Open the Mod Loader headers to see what they contain, specifically the Variables and Functions ones.&lt;br /&gt;
* If you are already experimented, take a look at the community driven [[Working with the Disassembly|disassembly]].&lt;br /&gt;
* Take a look at open source SADX/SA2 mods on GitHub to learn from them.&lt;br /&gt;
&lt;br /&gt;
If you want to quickly check if it&#039;s working, try to add &amp;lt;code&amp;gt;Rings = 999;&amp;lt;/code&amp;gt; in the OnFrame entry point, this is the ingame ring counter.&lt;br /&gt;
&lt;br /&gt;
If you have enabled the Debug Console in the Mod Manager options, you can print to it with:&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
PrintDebug(&amp;quot;text\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;After any modification, you need to rebuild the DLL, and move it to the mod folder again.&lt;br /&gt;
&lt;br /&gt;
Once you are familiar enough with the process, you can make your life easier with [[debugging]].&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-edit-mod-dllname.png&amp;diff=356</id>
		<title>File:Samm-edit-mod-dllname.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-edit-mod-dllname.png&amp;diff=356"/>
		<updated>2025-10-08T21:26:58Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-edit-mode-context-menu.png&amp;diff=355</id>
		<title>File:Samm-edit-mode-context-menu.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-edit-mode-context-menu.png&amp;diff=355"/>
		<updated>2025-10-08T21:26:12Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Vs-build-mode.png&amp;diff=354</id>
		<title>File:Vs-build-mode.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Vs-build-mode.png&amp;diff=354"/>
		<updated>2025-10-08T21:18:57Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Mod-example-dllexports.png&amp;diff=353</id>
		<title>File:Mod-example-dllexports.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Mod-example-dllexports.png&amp;diff=353"/>
		<updated>2025-10-08T21:16:13Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-add-new-item-form-cpp.png&amp;diff=352</id>
		<title>File:Visual-studio-add-new-item-form-cpp.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-add-new-item-form-cpp.png&amp;diff=352"/>
		<updated>2025-10-08T20:16:45Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-add-new-item.png&amp;diff=351</id>
		<title>File:Visual-studio-add-new-item.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-add-new-item.png&amp;diff=351"/>
		<updated>2025-10-08T20:12:08Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Dll-mod-project-folder-example-sadx.png&amp;diff=350</id>
		<title>File:Dll-mod-project-folder-example-sadx.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Dll-mod-project-folder-example-sadx.png&amp;diff=350"/>
		<updated>2025-10-08T20:04:12Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Github-download-repo.png&amp;diff=349</id>
		<title>File:Github-download-repo.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Github-download-repo.png&amp;diff=349"/>
		<updated>2025-10-08T19:52:14Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher-createproject.png&amp;diff=348</id>
		<title>File:Visual-studio-launcher-createproject.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher-createproject.png&amp;diff=348"/>
		<updated>2025-10-08T19:04:54Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher-template.png&amp;diff=347</id>
		<title>File:Visual-studio-launcher-template.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher-template.png&amp;diff=347"/>
		<updated>2025-10-08T18:57:34Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher.png&amp;diff=346</id>
		<title>File:Visual-studio-launcher.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-launcher.png&amp;diff=346"/>
		<updated>2025-10-08T18:53:08Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Visual-studio-installer.gif&amp;diff=345</id>
		<title>File:Visual-studio-installer.gif</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Visual-studio-installer.gif&amp;diff=345"/>
		<updated>2025-10-08T18:24:42Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Katana_SDK&amp;diff=333</id>
		<title>Katana SDK</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Katana_SDK&amp;diff=333"/>
		<updated>2025-10-08T00:10:41Z</updated>

		<summary type="html">&lt;p&gt;Kell: Start chunk model&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dreamcast SDK ==&lt;br /&gt;
Katana SDK (Dreamcast SDK for SEGA Library) was the official SEGA development kit that came with Dreamcast development units. The Dreamcast SDK had a number of libraries and APIs that many developers used in their games. The SDK evolved together with the console, and earlier versions of the SDK had fewer features or targeted different hardware. Updates to the SDK continued after the Dreamcast&#039;s release, and some releases were as late as 2001.&lt;br /&gt;
&lt;br /&gt;
The Dreamcast SDK consisted of several subsystems:&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Shinobi&#039;&#039;&#039; library set interfaced with the CPU, cache and memory.&lt;br /&gt;
* The &#039;&#039;&#039;Kamui&#039;&#039;&#039; API (low level) and the &#039;&#039;&#039;Ninja&#039;&#039;&#039; library (high level) provided access to graphics.&lt;br /&gt;
* The &#039;&#039;&#039;Manatee&#039;&#039;&#039; and &#039;&#039;&#039;Audio64&#039;&#039;&#039; subsystems interfaced with sound hardware.&lt;br /&gt;
&lt;br /&gt;
Over the years there have been multiple SDK leaks, including parts of source code for older revisions. For modding purposes, we should focus on the Ninja library, which is used by the Sonic Adventure games.&lt;br /&gt;
&lt;br /&gt;
== Common Types ==&lt;br /&gt;
The following types are used in Shinobi and Ninja headers:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Ninja type&lt;br /&gt;
!C type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|Sint8&lt;br /&gt;
|char&lt;br /&gt;
|1&lt;br /&gt;
|Signed 8-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Uint8&lt;br /&gt;
|unsigned char&lt;br /&gt;
|1&lt;br /&gt;
|Unsigned 8-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Sint16&lt;br /&gt;
|__int16&lt;br /&gt;
|2&lt;br /&gt;
|Signed 16-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Uint16&lt;br /&gt;
|unsigned __int16&lt;br /&gt;
|2&lt;br /&gt;
|Unsigned 16-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Sint32&lt;br /&gt;
|int&lt;br /&gt;
|4&lt;br /&gt;
|Signed 32-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Uint32&lt;br /&gt;
|unsigned int&lt;br /&gt;
|4&lt;br /&gt;
|Unsigned 32-bit integer&lt;br /&gt;
|-&lt;br /&gt;
|Bool&lt;br /&gt;
|unsigned int&lt;br /&gt;
|4&lt;br /&gt;
|Unsigned 32-bit integer that is either TRUE (1) or FALSE (0)&lt;br /&gt;
|-&lt;br /&gt;
|Float and Float32&lt;br /&gt;
|float&lt;br /&gt;
|4&lt;br /&gt;
|32-bit floating point&lt;br /&gt;
|-&lt;br /&gt;
|Float64&lt;br /&gt;
|double&lt;br /&gt;
|8&lt;br /&gt;
|64-bit floating point&lt;br /&gt;
|-&lt;br /&gt;
|Void&lt;br /&gt;
|void&lt;br /&gt;
|&lt;br /&gt;
|Pointer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ninja Model Formats ==&lt;br /&gt;
The Ninja library can use two model formats, the Basic model and the Chunk model. Basic models were introduced early on, while Chunk models were added later as a format that is optimized for better performance on Dreamcast hardware. The Basic format is easier to read as text.&lt;br /&gt;
&lt;br /&gt;
=== Ninja Basic Model ===&lt;br /&gt;
The Basic model consists of the following structs:&lt;br /&gt;
&lt;br /&gt;
==== Material struct (&amp;lt;code&amp;gt;NJS_MATERIAL&amp;lt;/code&amp;gt;) and Material Array ====&lt;br /&gt;
The material affects how the model&#039;s surface looks. It defines which texture to use, whether to use environment mapping etc.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|diffuse&lt;br /&gt;
|0&lt;br /&gt;
|NJS_COLOR&lt;br /&gt;
|4&lt;br /&gt;
|Diffuse color.&lt;br /&gt;
|In SA1 with palette lighting, only alpha is used.&lt;br /&gt;
|-&lt;br /&gt;
|specular&lt;br /&gt;
|0x4&lt;br /&gt;
|NJS_COLOR&lt;br /&gt;
|4&lt;br /&gt;
|Specular color.&lt;br /&gt;
|In SA1 with palette lighting, only alpha is used. The alpha value of 0 is treated as the &amp;quot;ignore specular&amp;quot; flag.&lt;br /&gt;
|-&lt;br /&gt;
|exponent&lt;br /&gt;
|0x8&lt;br /&gt;
|Float&lt;br /&gt;
|4&lt;br /&gt;
|Specular color strength.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|attr_texId&lt;br /&gt;
|0xC&lt;br /&gt;
|Uint32&lt;br /&gt;
|4&lt;br /&gt;
|Texture ID.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|attrflags&lt;br /&gt;
|0x10&lt;br /&gt;
|Uint32&lt;br /&gt;
|4&lt;br /&gt;
|Material flags.&lt;br /&gt;
|Bits 31-29 and 28-26 are used for source and destination alpha blending instructions respectively.&lt;br /&gt;
|}&lt;br /&gt;
Size: 20 bytes (0x14).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NJS_COLOR&amp;lt;/code&amp;gt; is a union that can be either &amp;lt;code&amp;gt;NJS_BGRA&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;NJS_TEX&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Uint32&amp;lt;/code&amp;gt; (4 bytes).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NJS_BGRA&amp;lt;/code&amp;gt;is a 4-byte struct that consists of blue, green, red and alpha values ranging from 0 to 255. For example, the color &amp;lt;code&amp;gt;A255 R178 G178 B178&amp;lt;/code&amp;gt; would be &amp;lt;code&amp;gt;0xFFB2B2B2&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NJS_TEX&amp;lt;/code&amp;gt; (4 bytes) is a struct commonly used in UVs. It consists of two &amp;lt;code&amp;gt;Sint16&amp;lt;/code&amp;gt; values: one for U (horizontal) and one for V (vertical). UVs used in SA1 range from 0 to 255.&lt;br /&gt;
&lt;br /&gt;
The following flags can be used in &amp;lt;code&amp;gt;attrflags&amp;lt;/code&amp;gt;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Flag name&lt;br /&gt;
!Flag bit&lt;br /&gt;
!Description&lt;br /&gt;
!Comments&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_IGNORE_LIGHT&lt;br /&gt;
|BIT_25&lt;br /&gt;
|Ignore lighting.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_USE_FLAT&lt;br /&gt;
|BIT_24&lt;br /&gt;
|Flat lighting.&lt;br /&gt;
|Has no effect when palette-based lighting in SA1 is used.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_DOUBLE_SIDE&lt;br /&gt;
|BIT_23&lt;br /&gt;
|Double-sided mesh.&lt;br /&gt;
|May be used for collision.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_USE_ENV&lt;br /&gt;
|BIT_22&lt;br /&gt;
|Enable environment mapping.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_USE_TEXTURE&lt;br /&gt;
|BIT_21&lt;br /&gt;
|Enable texture.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_USE_ALPHA&lt;br /&gt;
|BIT_20&lt;br /&gt;
|Enable transparency.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_IGNORE_SPECULAR&lt;br /&gt;
|BIT_19&lt;br /&gt;
|Disable specular lighting.&lt;br /&gt;
|Used for specular palette selection in palette-based lighting in SA1.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_FLIP_U    &lt;br /&gt;
|BIT_18&lt;br /&gt;
|Flip Us.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_FLIP_V&lt;br /&gt;
|BIT_17&lt;br /&gt;
|Flip Vs.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_CLAMP_U&lt;br /&gt;
|BIT_16&lt;br /&gt;
|Clamp Us.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_CLAMP_V&lt;br /&gt;
|BIT_15&lt;br /&gt;
|Clamp Vs.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_USE_ANISOTROPIC&lt;br /&gt;
|BIT_12&lt;br /&gt;
|Enable anisotropic filtering,&lt;br /&gt;
|Unused.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_FLAG_PICK&lt;br /&gt;
|BIT_7&lt;br /&gt;
|&amp;quot;Pick status&amp;quot;&lt;br /&gt;
|Unused.&lt;br /&gt;
|}&lt;br /&gt;
Alpha modes can be as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Source alpha&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Value&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_ZERO&lt;br /&gt;
|0&lt;br /&gt;
|Zero.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_ONE&lt;br /&gt;
|BIT_29&lt;br /&gt;
|One.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_OTHER&lt;br /&gt;
|BIT_30&lt;br /&gt;
|Other color.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_INV_OTHER&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_30 | BIT_29&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse other color.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_SRC&lt;br /&gt;
|BIT_31&lt;br /&gt;
|Source alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_INV_SRC&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_31 | BIT_29&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse source alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_DST&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_31 | BIT_30&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Destination alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_SA_INV_DST&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_31 | BIT_30 | BIT_29&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse destination alpha.&lt;br /&gt;
|}&lt;br /&gt;
!Destination alpha&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Value&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_ZERO&lt;br /&gt;
|0&lt;br /&gt;
|Zero.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_ONE&lt;br /&gt;
|BIT_26&lt;br /&gt;
|One.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_OTHER&lt;br /&gt;
|BIT_27&lt;br /&gt;
|Other color.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_INV_OTHER&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_27 | BIT_26&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse other color.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_SRC&lt;br /&gt;
|BIT_28&lt;br /&gt;
|Source alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_INV_SRC&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_28 | BIT_26&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse source alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_DST&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_28 | BIT_27&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Destination alpha.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_DA_INV_DST&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;BIT_28| BIT_27 |BIT_26&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|Inverse destination alpha.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
Basic models&#039; materials are stored in arrays of &amp;lt;code&amp;gt;NJS_MATERIAL&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_MATERIAL matlist_004451A8[] = {&lt;br /&gt;
	{ { 0xFFFFFFFF }, { 0xFFFFFFFF }, 11, 14, NJD_D_100 | NJD_FILTER_BILINEAR | NJD_FLAG_CLAMP_V | NJD_FLAG_CLAMP_U | NJD_FLAG_IGNORE_SPECULAR | NJD_FLAG_USE_TEXTURE | NJD_DA_INV_SRC | NJD_SA_SRC },&lt;br /&gt;
	{ { 0xFFB2B2B2 }, { 0xFFFFFFFF }, 11, 13, NJD_D_100 | NJD_FILTER_BILINEAR | NJD_FLAG_CLAMP_V | NJD_FLAG_CLAMP_U | NJD_FLAG_IGNORE_SPECULAR | NJD_FLAG_USE_ALPHA | NJD_FLAG_USE_TEXTURE | NJD_DA_INV_SRC | NJD_SA_SRC },&lt;br /&gt;
	{ { 0xFFB2B2B2 }, { 0xFFFFFFFF }, 11, 15, NJD_D_100 | NJD_FILTER_BILINEAR | NJD_FLAG_CLAMP_V | NJD_FLAG_CLAMP_U | NJD_FLAG_IGNORE_SPECULAR | NJD_FLAG_USE_TEXTURE | NJD_DA_INV_SRC | NJD_SA_SRC }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Poly Array ====&lt;br /&gt;
The poly array in an array of &amp;lt;code&amp;gt;Sint16&amp;lt;/code&amp;gt; that lists the model&#039;s primitives (polygons). It is commonly formatted with the number of vertices (points) followed by vertex indices. The indices are used to pick the specific vertices from the model&#039;s vertices array.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a polys array. The &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt; in each new line indicates the number of vertices in the surface, and the following four values are vertex indices.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Sint16 poly_0000002C[] = {&lt;br /&gt;
	4, 13, 12, 5, 4,&lt;br /&gt;
	4, 9, 8, 1, 0,&lt;br /&gt;
	4, 11, 10, 3, 2,&lt;br /&gt;
	4, 15, 14, 7, 6&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The number of vertices can be ORd with &amp;lt;code&amp;gt;0x8000&amp;lt;/code&amp;gt;, which indicates a flipped surface. TODO: Confirm this.&lt;br /&gt;
&lt;br /&gt;
==== UV Array ====&lt;br /&gt;
The UV array is an array of &amp;lt;code&amp;gt;NJS_TEX&amp;lt;/code&amp;gt;. UVs determine how the texture is applied to the model&#039;s surface. For exampled, bigger UV values will make the texture &amp;quot;zoomed in&amp;quot;, adding values to U will make the texture offset horizontally etc. UVs are per-polygon.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_TEX uv_000003A4[] = {&lt;br /&gt;
	{ 130, 145 },&lt;br /&gt;
	{ 212, 225 },&lt;br /&gt;
	{ 124, 230 },&lt;br /&gt;
	// And so on...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vertex Color Array ====&lt;br /&gt;
This is an array of &amp;lt;code&amp;gt;NJS_COLOR&amp;lt;/code&amp;gt; that determines the colors of the model&#039;s vertices. Vertex colors are used per-polygon, not per-vertex.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_COLOR vcolor_0000003C[] = {&lt;br /&gt;
	{ 0xFFFFFFDF },&lt;br /&gt;
	{ 0xFFFFFFFF },&lt;br /&gt;
	{ 0xFFFFDFBF },&lt;br /&gt;
	{ 0xFFFFFFFF },&lt;br /&gt;
	{ 0xFFFFDFBF },&lt;br /&gt;
	// And so on...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Polynormal Array ====&lt;br /&gt;
Normals determine the model&#039;s lighting and environment mapping distortion. Normals can be specified per-vertex or por-polygon. Almost no models in SA1 use per-poly normals (polynormals), with the exception of Tails&#039; tails and Sonic&#039;s stretchy shoes. When polynormals are used, this is the array they are expected to be in.&lt;br /&gt;
&lt;br /&gt;
Normals and polynormals are defined as arrays of &amp;lt;code&amp;gt;NJS_VECTOR&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;NJS_VECTOR&amp;lt;/code&amp;gt; consists of three floats for X, Y and Z.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_VECTOR polynormal_007383D8[] = {&lt;br /&gt;
	{ 0 },&lt;br /&gt;
	{ 0 },&lt;br /&gt;
	{ 0 },&lt;br /&gt;
	{ 0 },&lt;br /&gt;
	{ 0 },&lt;br /&gt;
	{ 0 }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Polygon Attribute Array ====&lt;br /&gt;
This is an array of &amp;lt;code&amp;gt;Uint32&amp;lt;/code&amp;gt; containing polygon-specific attributes. It is not used in Sonic Adventure games.&lt;br /&gt;
&lt;br /&gt;
==== Meshset Struct (&amp;lt;code&amp;gt;NJS_MESHSET&amp;lt;/code&amp;gt;) and Meshset Array ====&lt;br /&gt;
Multiple connected polygons form meshes. The &amp;lt;code&amp;gt;NJS_MESHSET&amp;lt;/code&amp;gt; struct defines a single mesh. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|type_matId&lt;br /&gt;
|0&lt;br /&gt;
|Uint16&lt;br /&gt;
|2&lt;br /&gt;
|Diffuse color.&lt;br /&gt;
|Bits 0-13 are material id (0-4095) in the material array.&lt;br /&gt;
Bits 14-15 are meshset type bits (see below).&lt;br /&gt;
|-&lt;br /&gt;
|nbMesh&lt;br /&gt;
|0x2&lt;br /&gt;
|Uint16&lt;br /&gt;
|2&lt;br /&gt;
|Number of meshes.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*meshes&lt;br /&gt;
|0x4&lt;br /&gt;
|Sint16*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the poly array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*attrs&lt;br /&gt;
|0x8&lt;br /&gt;
|Uint32*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the poly attribute array.&lt;br /&gt;
|Unused in SA games.&lt;br /&gt;
|-&lt;br /&gt;
|*normals&lt;br /&gt;
|0xC&lt;br /&gt;
|NJS_VECTOR*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the polynormal array.&lt;br /&gt;
|Almost never used.&lt;br /&gt;
|-&lt;br /&gt;
|*vertcolor&lt;br /&gt;
|0x10&lt;br /&gt;
|NJS_COLOR*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the vertex color array.&lt;br /&gt;
|Unused in SA1 DC, used in SADX.&lt;br /&gt;
|-&lt;br /&gt;
|*vertuv&lt;br /&gt;
|0x14&lt;br /&gt;
|NJS_TEX*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the UV array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|buffer&lt;br /&gt;
|0x18&lt;br /&gt;
|void&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the Direct3D mesh buffer.&lt;br /&gt;
|Always null.&lt;br /&gt;
SADX PC 2004, SADX X360 and SADX PS3 only.&lt;br /&gt;
|}&lt;br /&gt;
In the 2004 PC port of SADX this struct contains an extra field for the mesh buffer (&amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt;). This version of the struct is used in the PC, X360 and PS3 versions. &lt;br /&gt;
&lt;br /&gt;
SA2 and Gamecube versions of SADX use the original struct without the extra field.&lt;br /&gt;
&lt;br /&gt;
In [[Mod Loaders|SADX Mod Loader]] headers the original Ninja version is &amp;lt;code&amp;gt;NJS_MESHSET&amp;lt;/code&amp;gt;, and the one with the extra field is &amp;lt;code&amp;gt;NJS_MESHSET_SADX&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the [[SADX X360 Prototype with Symbols|SADX X360 prototype with symbols]], the one with the extra field is &amp;lt;code&amp;gt;NJS_MESHSET&amp;lt;/code&amp;gt;, and the original Ninja version is &amp;lt;code&amp;gt;NJS_MESHSET_OLD&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The size of the original &amp;lt;code&amp;gt;NJS_MESHSET&amp;lt;/code&amp;gt; is 24 (&amp;lt;code&amp;gt;0x18&amp;lt;/code&amp;gt;) bytes, and the size of &amp;lt;code&amp;gt;NJS_MESHSET_SADX&amp;lt;/code&amp;gt; is 28 (&amp;lt;code&amp;gt;0x1C&amp;lt;/code&amp;gt;) bytes.&lt;br /&gt;
&lt;br /&gt;
Meshset type bits are as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Meshset type&lt;br /&gt;
!Value&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|NJD_MESHSET_3&lt;br /&gt;
|0x0000&lt;br /&gt;
|Default mesh type (three vertices). Technically identical to &amp;lt;code&amp;gt;NJD_MESHSET_TRIMESH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_MESHSET_4&lt;br /&gt;
|0x4000&lt;br /&gt;
|Quad (four vertices).&lt;br /&gt;
|-&lt;br /&gt;
|NJD_MESHSET_N&lt;br /&gt;
|0x8000&lt;br /&gt;
|N-Gon (custom number of vertices).&lt;br /&gt;
|-&lt;br /&gt;
|NJD_MESHSET_TRIMESH&lt;br /&gt;
|0xC000&lt;br /&gt;
|Trimesh, the most common meshset type.&lt;br /&gt;
|-&lt;br /&gt;
|NJS_MESHSET_MASK&lt;br /&gt;
|0xC000&lt;br /&gt;
|Meshset type mask.&lt;br /&gt;
|}&lt;br /&gt;
To get the material ID from the &amp;lt;code&amp;gt;type_matId&amp;lt;/code&amp;gt; field in your code, use &amp;lt;code&amp;gt;type_matId &amp;amp; ~NJD_MESHSET_MASK&amp;lt;/code&amp;gt;. To get the mesh type, use &amp;lt;code&amp;gt;type_matId &amp;gt;&amp;gt; 0xE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Meshes in Basic models are stored in arrays of NJS_MESHSET:&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_MESHSET_SADX meshlist_00000294[] = {&lt;br /&gt;
	{ NJD_MESHSET_TRIMESH | 0, 9, poly_00000044, NULL, NULL, NULL, uv_00000128, NULL },&lt;br /&gt;
	{ NJD_MESHSET_TRIMESH | 1, 10, poly_000000A4, NULL, NULL, NULL, uv_000001C4, NULL },&lt;br /&gt;
	{ NJD_MESHSET_TRIMESH | 2, 3, poly_00000108, NULL, NULL, NULL, uv_00000264, NULL }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vertex Array ====&lt;br /&gt;
The model&#039;s vertices are in an array of &amp;lt;code&amp;gt;NJS_POINT3&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;NJS_VECTOR&amp;lt;/code&amp;gt; in Mod Loader headers).&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;NJS_VECTOR vertex_00000ADC[] = {&lt;br /&gt;
	{ 0, 26.04398f, 0 },&lt;br /&gt;
	{ 3.602116f, 18.50802f, 0 },&lt;br /&gt;
	{ 1.801057f, 18.50802f, -3.119523f },&lt;br /&gt;
	{ -1.801059f, 18.50802f, -3.119523f },&lt;br /&gt;
	// And so on...&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Normal Array ====&lt;br /&gt;
The model&#039;s normals are in an array of &amp;lt;code&amp;gt;NJS_VECTOR&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NJS_VECTOR normal_00000D28[] = {&lt;br /&gt;
	{ 0, 1, 0 },&lt;br /&gt;
	{ 0.902229f, 0.431257f, 0 },&lt;br /&gt;
	{ 0.451115f, 0.431256f, -0.781354f },&lt;br /&gt;
	{ -0.451115f, 0.431256f, -0.781354f },&lt;br /&gt;
	// And so on...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Model Struct (&amp;lt;code&amp;gt;NJS_MODEL&amp;lt;/code&amp;gt;) ====&lt;br /&gt;
The Model struct combines all the things mentioned above and adds model center coordinates and radius.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|*points&lt;br /&gt;
|0&lt;br /&gt;
|NJS_POINT3*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the vertex array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*normals&lt;br /&gt;
|0x4&lt;br /&gt;
|NJS_VECTOR*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the normal array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|nbPoint&lt;br /&gt;
|0x8&lt;br /&gt;
|Sint32&lt;br /&gt;
|4&lt;br /&gt;
|Number of vertices.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*meshsets&lt;br /&gt;
|0xC&lt;br /&gt;
|NJS_MESHSET*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the meshset array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*mats&lt;br /&gt;
|0x10&lt;br /&gt;
|NJS_MATERIAL*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the material array.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|nbMeshset&lt;br /&gt;
|0x14&lt;br /&gt;
|Uint16&lt;br /&gt;
|2&lt;br /&gt;
|Number of meshsets.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|nbMat&lt;br /&gt;
|0x16&lt;br /&gt;
|Uint16&lt;br /&gt;
|2&lt;br /&gt;
|Number of materials.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|center&lt;br /&gt;
|0x18&lt;br /&gt;
|NJS_POINT3&lt;br /&gt;
|12&lt;br /&gt;
|Model center.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|r&lt;br /&gt;
|0x24&lt;br /&gt;
|Float&lt;br /&gt;
|4&lt;br /&gt;
|Model radius.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*buffer&lt;br /&gt;
|0x28&lt;br /&gt;
|void&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the Direct3D mesh buffer.&lt;br /&gt;
|Always null.&lt;br /&gt;
SADX PC 2004, SADX X360 and SADX PS3 only.&lt;br /&gt;
|}&lt;br /&gt;
In the 2004 PC port of SADX this struct contains an extra field for the mesh buffer (&amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt;). This version of the struct is used in the PC, X360 and PS3 versions.&lt;br /&gt;
&lt;br /&gt;
SA2 and Gamecube versions of SADX use the original struct without the extra field.&lt;br /&gt;
&lt;br /&gt;
In [[Mod Loaders|SADX Mod Loader]] headers the original Ninja version is &amp;lt;code&amp;gt;NJS_MODEL&amp;lt;/code&amp;gt;, and the one with the extra field is &amp;lt;code&amp;gt;NJS_MODEL_SADX&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the [[SADX X360 Prototype with Symbols|SADX X360 prototype with symbols]], the one with the extra field is &amp;lt;code&amp;gt;NJS_MODEL&amp;lt;/code&amp;gt;, and the original Ninja version is &amp;lt;code&amp;gt;NJS_MODEL_OLD&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The size of the original &amp;lt;code&amp;gt;NJS_MODEL&amp;lt;/code&amp;gt; is 40 (&amp;lt;code&amp;gt;0x28&amp;lt;/code&amp;gt;) bytes, and the size of &amp;lt;code&amp;gt;NJS_MODEL_SADX&amp;lt;/code&amp;gt; is 44 (&amp;lt;code&amp;gt;0x2C&amp;lt;/code&amp;gt;) bytes.&lt;br /&gt;
&lt;br /&gt;
In old modding terminology, the Model struct was referred to as the &amp;quot;attach&amp;quot; struct. You can still see this label in SA Tools&#039; C exports.&lt;br /&gt;
&lt;br /&gt;
==== Object Struct (&amp;lt;code&amp;gt;NJS_OBJECT&amp;lt;/code&amp;gt;) ====&lt;br /&gt;
Ninja models use a node-like hierarchy, and the Object struct represents a single node. The size of NJS_OBJECT is 52 (&amp;lt;code&amp;gt;0x34&amp;lt;/code&amp;gt;) bytes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|evalflags&lt;br /&gt;
|0&lt;br /&gt;
|Uint32&lt;br /&gt;
|4&lt;br /&gt;
|Model evaluation flags (see below).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*model&lt;br /&gt;
|0x4&lt;br /&gt;
|NJS_MODEL*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the &amp;lt;code&amp;gt;NJS_MODEL&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|pos&lt;br /&gt;
|0x8&lt;br /&gt;
|Float[3]&lt;br /&gt;
|12&lt;br /&gt;
|Model position (X, Y, Z).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|ang&lt;br /&gt;
|0x14&lt;br /&gt;
|Angle[3]&lt;br /&gt;
|12&lt;br /&gt;
|Model rotation (X, Y, Z).&lt;br /&gt;
|Angle is the same as Sint32.&lt;br /&gt;
|-&lt;br /&gt;
|scl&lt;br /&gt;
|0x20&lt;br /&gt;
|Float[3]&lt;br /&gt;
|12&lt;br /&gt;
|Model scale (X, Y, Z).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*child&lt;br /&gt;
|0x2C&lt;br /&gt;
|NJS_OBJECT*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the child model in the hierarchy.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|*sibling&lt;br /&gt;
|0x30&lt;br /&gt;
|NJS_OBJECT*&lt;br /&gt;
|4&lt;br /&gt;
|Pointer to the sibling model in the hierarchy.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The following evaluation flags can be used:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Flag bits&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_UNIT_POS&lt;br /&gt;
|BIT_0&lt;br /&gt;
|Ignore the model&#039;s position.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_UNIT_ANG&lt;br /&gt;
|BIT_1&lt;br /&gt;
|Ignore the model&#039;s rotation.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_UNIT_SCL&lt;br /&gt;
|BIT_2&lt;br /&gt;
|Ignore the model&#039;s scale.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_HIDE&lt;br /&gt;
|BIT_3&lt;br /&gt;
|Do not render the model.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_BREAK&lt;br /&gt;
|BIT_4&lt;br /&gt;
|Node is the end of the hierarchy (do not check children).&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_ZXY_ANG&lt;br /&gt;
|BIT_5&lt;br /&gt;
|Inverted order of rotation.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_SKIP&lt;br /&gt;
|BIT_6&lt;br /&gt;
|Do not animate (ignore) this node.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_SHAPE_SKIP&lt;br /&gt;
|BIT_7&lt;br /&gt;
|Do not animate (ignore) this node in shape animations.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_CLIP&lt;br /&gt;
|BIT_8&lt;br /&gt;
|If this node is clipped, do not clip child nodes.&lt;br /&gt;
|-&lt;br /&gt;
|NJD_EVAL_MODIFIER&lt;br /&gt;
|BIT_9&lt;br /&gt;
|The node has a modifier volume.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Ninja Chunk Model ===&lt;br /&gt;
The chunk model format is a sequence of instructions called chunks. A chunk can modify the rendering context or supply vertex and strip data. This is more efficient as vertex data is preformatted and the rendering context is less often modified. However, it is a bit more involving to parse.&lt;br /&gt;
&lt;br /&gt;
==== Chunk Model Structure ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Size&lt;br /&gt;
!Description&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|vlist&lt;br /&gt;
|0&lt;br /&gt;
|Sint32*&lt;br /&gt;
|4&lt;br /&gt;
|&amp;quot;Vertex&amp;quot; chunk list&lt;br /&gt;
|Only for vertex chunks, separate for 32bit access + easier preprocessing&lt;br /&gt;
|-&lt;br /&gt;
|plist&lt;br /&gt;
|4&lt;br /&gt;
|Sint16*&lt;br /&gt;
|4&lt;br /&gt;
|&amp;quot;Polygon&amp;quot; chunk list&lt;br /&gt;
|Remaining chunk types&lt;br /&gt;
|-&lt;br /&gt;
|center&lt;br /&gt;
|8&lt;br /&gt;
|NJS_VECTOR&lt;br /&gt;
|12&lt;br /&gt;
|Model center&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|r&lt;br /&gt;
|20&lt;br /&gt;
|Float&lt;br /&gt;
|4&lt;br /&gt;
|Model radius&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The chunk lists shall be parsed continuously until the &amp;quot;end&amp;quot; chunk (255) is reached.&lt;br /&gt;
&lt;br /&gt;
==== Vertex chunk list ====&lt;br /&gt;
The library first parses the vertex chunk list. A vertex chunk contains a list of vertices. Each vertex will be placed in an intermediate vertex buffer that will be used for strip indices.&lt;br /&gt;
&lt;br /&gt;
A vertex chunk is composed of a header, followed by data:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (32 bits)&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Vertex data information (32 bits)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Data&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-15)&lt;br /&gt;
!Next chunk (16-31)&lt;br /&gt;
!Vertex count (0-15)&lt;br /&gt;
!Index offset (16-31)&lt;br /&gt;
|-&lt;br /&gt;
|Vertex type&lt;br /&gt;
|Chunk size - 1&lt;br /&gt;
|Number of vertices&lt;br /&gt;
|Start position in intermediate vbuffer&lt;br /&gt;
|Depends on type&lt;br /&gt;
|}&lt;br /&gt;
The data depends on the vertex chunk type:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Vertex chunk&lt;br /&gt;
!Components&lt;br /&gt;
!Vertex stream&lt;br /&gt;
!Comment&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_SH&lt;br /&gt;
|Position&lt;br /&gt;
|x, y, z,1.0f, ...&lt;br /&gt;
|SH4 optimized (aligned)&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_SH&lt;br /&gt;
|Position + Normal&lt;br /&gt;
|x, y, z,1.0f, nx, ny, ny, 0.0f, ...&lt;br /&gt;
|SH4 optimized (aligned)&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV&lt;br /&gt;
|Position&lt;br /&gt;
|x, y, z, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_D8&lt;br /&gt;
|Position + Diffuse&lt;br /&gt;
|x, y, z, D8888, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_UF&lt;br /&gt;
|Position + UserFlag&lt;br /&gt;
|x, y, z, UF32&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_NF&lt;br /&gt;
|Position + NinjaFlag&lt;br /&gt;
|x, y, z, NF32&lt;br /&gt;
|Used for weights&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_S5&lt;br /&gt;
|Position + Diffuse + Specular&lt;br /&gt;
|x, y, z, D565, S565, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_S4&lt;br /&gt;
|Position + Diffuse + Specular&lt;br /&gt;
|x, y, z, D4444, S565, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_IN &lt;br /&gt;
|Position + Diffuse + Specular&lt;br /&gt;
|x, y, z, D16, S16, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN&lt;br /&gt;
|Position + Normal&lt;br /&gt;
|x, y, z, nx, ny, nz, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_D8&lt;br /&gt;
|Position + Normal + Diffuse&lt;br /&gt;
|x, y, z, nx, ny, nz, D8888, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_UF&lt;br /&gt;
|Position + Normal + Diffuse + UserFlag&lt;br /&gt;
|x, y, z, nx, ny, nz, D8888, UF32, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_NF&lt;br /&gt;
|Position + Normal + Diffuse + NinjaFlag&lt;br /&gt;
|x, y, z, nx, ny, nz, D8888, NF32, ...&lt;br /&gt;
|Used for weights&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_S5&lt;br /&gt;
|Position + Normal + Diffuse + Specular&lt;br /&gt;
|x, y, z, nx, ny, nz, D565, S565, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_S4&lt;br /&gt;
|Position + Normal + Diffuse + Specular&lt;br /&gt;
|x, y, z, nx, ny, nz, D4444, S565, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VN_IN &lt;br /&gt;
|Position + Normal + Diffuse + Specular&lt;br /&gt;
|x, y, z, nx, ny, nz, D16, S16, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VNX&lt;br /&gt;
|Position + Normal&lt;br /&gt;
|x, y, z, nx10, ny10, nz(10), pad, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VNX_D8&lt;br /&gt;
|Position + Normal + Diffuse&lt;br /&gt;
|x, y, z, nx10, ny10, nz(10), pad, D8888, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CV_VNX_UF&lt;br /&gt;
|Position + Normal + UserFlag&lt;br /&gt;
|x, y, z, nx10, ny10, nz(10), pad, UF32, ...&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Note that the library only supports &#039;&#039;&#039;one chunk type per model&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The data is continuous until the end chunk is reached (255).&lt;br /&gt;
&lt;br /&gt;
==== Polygon chunk list ====&lt;br /&gt;
The library then processes the polygon chunk list, which consists of chunks that specify how to render the vertices.&lt;br /&gt;
&lt;br /&gt;
These chunks follow the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (16 bits)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |&#039;&#039;Next chunk, optional&#039;&#039;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |&#039;&#039;Data, optional&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-7)&lt;br /&gt;
!Headbits (8-15)&lt;br /&gt;
|-&lt;br /&gt;
|Vertex type&lt;br /&gt;
|Depends on type&lt;br /&gt;
|&#039;&#039;Chunk size - 2&#039;&#039;&lt;br /&gt;
|&#039;&#039;Depends on type&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
Chunks are continuous until the end chunk is reached (255).&lt;br /&gt;
&lt;br /&gt;
There are 5 categories of polygon chunks:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Bits&#039;&#039;&#039; chunk (fixed 16 bit size) : some rendering attributes&lt;br /&gt;
* &#039;&#039;&#039;Tiny&#039;&#039;&#039; chunks (fixed 32 bit size) : texture ID&lt;br /&gt;
* &#039;&#039;&#039;Material&#039;&#039;&#039; chunks : diffuse color, ambient color, specular color, blending flags&lt;br /&gt;
* &#039;&#039;&#039;Volume&#039;&#039;&#039; chunks : collision/modifier volumes&lt;br /&gt;
* &#039;&#039;&#039;Strip&#039;&#039;&#039; chunks : strip data&lt;br /&gt;
&lt;br /&gt;
===== Bits chunks =====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (16 bits)&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-7)&lt;br /&gt;
!Headbits (8-15)&lt;br /&gt;
|}&lt;br /&gt;
The next chunk is directly after.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
===== Tiny chunks =====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (16 bits)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Data (16 bits)&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-7)&lt;br /&gt;
!Headbits (8-15)&lt;br /&gt;
|}&lt;br /&gt;
The next chunk is directly after.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
===== Material chunks =====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (16 bits)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Next chunk&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Data&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-7)&lt;br /&gt;
!Headbits (8-15)&lt;br /&gt;
|}&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
===== Volume chunks =====&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
===== Strip chunks =====&lt;br /&gt;
A strip chunk renders a triangle strip using vertices from the intermediate buffer generated by the vertex chunk list.&lt;br /&gt;
&lt;br /&gt;
It can contain additional information, such as UV coordinates, vertex color or user data.&lt;br /&gt;
&lt;br /&gt;
The chunk structure is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Header (16 bits)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Next chunk&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Strip data information&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; |Data, optional&lt;br /&gt;
|-&lt;br /&gt;
!Type (0-7)&lt;br /&gt;
!Headbits (8-15)&lt;br /&gt;
!Strip count (0-13)&lt;br /&gt;
!User area size (14-15)&lt;br /&gt;
|-&lt;br /&gt;
|Strip type&lt;br /&gt;
|Rendering flags&lt;br /&gt;
|Chunk size - 2&lt;br /&gt;
|Number of strips&lt;br /&gt;
|NJD_UFO_0 = 0 bits&lt;br /&gt;
NJD_UFO_1 = 16 bits&lt;br /&gt;
NJD_UFO_2 = 32 bits&lt;br /&gt;
|Depends on type&lt;br /&gt;
|}&lt;br /&gt;
The data itself follows this structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Strip header&lt;br /&gt;
! colspan=&amp;quot;7&amp;quot; |Strip stream&lt;br /&gt;
|-&lt;br /&gt;
|Length (0-14)&lt;br /&gt;
|Winding flag (15)&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |First element&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Second element&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |Element N ....&lt;br /&gt;
|-&lt;br /&gt;
|Number of vertices&lt;br /&gt;
|If set, reverse order&lt;br /&gt;
|Index&lt;br /&gt;
|Data&lt;br /&gt;
|Index&lt;br /&gt;
|Data&lt;br /&gt;
|Index&lt;br /&gt;
|Data&lt;br /&gt;
|&#039;&#039;User area (optional)&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; The user area is per-triangle, so it only starts at the third element, from there every other vertex is another triangle.&lt;br /&gt;
&lt;br /&gt;
The data stream depends on the strip type:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Strip chunk&lt;br /&gt;
!Components&lt;br /&gt;
!Data stream&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS&lt;br /&gt;
|None&lt;br /&gt;
|index&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVN&lt;br /&gt;
|UV (255 = 1.0)&lt;br /&gt;
|index, u, v&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVH&lt;br /&gt;
|UV (1023 = 1.0)&lt;br /&gt;
|index, u, v&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_VN&lt;br /&gt;
|Normal&lt;br /&gt;
|index, nx, ny, nz&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVN_VN&lt;br /&gt;
|UV (255), normal&lt;br /&gt;
|index, u, v, nx, ny, nz&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVH_VN&lt;br /&gt;
|UV (1023), normal&lt;br /&gt;
|index, u, v, nx, ny, nz&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_D8&lt;br /&gt;
|Diffuse&lt;br /&gt;
|index, ar, gb&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVN_D8&lt;br /&gt;
|UV (255), diffuse&lt;br /&gt;
|index, u, v, ar, gb&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVH_D8&lt;br /&gt;
|UV (1023), diffuse&lt;br /&gt;
|index, u, v, ar, gb&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_2 &lt;br /&gt;
|None&lt;br /&gt;
|index&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVN2&lt;br /&gt;
|UV (255)&lt;br /&gt;
|index, u, v&lt;br /&gt;
|-&lt;br /&gt;
|NJD_CS_UVH2&lt;br /&gt;
|UV (1023)&lt;br /&gt;
|index, u, v&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Ninja Motions and Actions ===&lt;br /&gt;
&lt;br /&gt;
== Ports of Ninja to Other Platforms ==&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Cheat_Codes&amp;diff=286</id>
		<title>Creating Mods/Cheat Codes</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Cheat_Codes&amp;diff=286"/>
		<updated>2025-10-05T20:32:31Z</updated>

		<summary type="html">&lt;p&gt;Kell: Add section links and fix minor mistake&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Sonic Adventure DX and Sonic Adventure 2: Battle Mod Loaders allow you to edit the game&#039;s code and memory without resorting to a DLL mod. The syntax is similar to cheat code for consoles, such as Action Replay code. This is useful for simple modifications where a DLL would be overkill.&lt;br /&gt;
&lt;br /&gt;
== Creating a cheat code ==&lt;br /&gt;
&lt;br /&gt;
=== Using the SA Mod Manager ===&lt;br /&gt;
First edit your mod by right clicking it and clicking on Edit mod, or by selecting it and pressing Ctrl + E.&lt;br /&gt;
[[File:Samm-editmod-context.png|none|508x508px]]&lt;br /&gt;
Then go in the &amp;quot;Codes&amp;quot; tab and click on &amp;quot;New code&amp;quot;.&lt;br /&gt;
[[File:Samm-editmode-codestab.png|none|502x502px]]&lt;br /&gt;
You are now in the cheat code editor :&lt;br /&gt;
[[File:Samm-editmode-codeeditor.png|none|500x500px]]&lt;br /&gt;
Fields are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: short name for the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: author(s) of the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Type*&#039;&#039;&#039;: &amp;quot;Code&amp;quot; will make your cheat code run every frame, &amp;quot;Patch&amp;quot; will make it run once at start up.&lt;br /&gt;
* &#039;&#039;&#039;Is Required&#039;&#039;&#039;: if checked, the cheat code will be forced on and won&#039;t appear in the Mod Manager &amp;quot;Codes&amp;quot; tab.&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: description of the cheat code.&lt;br /&gt;
&lt;br /&gt;
To write the code, see [[Creating mods/Cheat Codes#Writing a cheat code|Writing a cheat code]].&lt;br /&gt;
&lt;br /&gt;
When finished, save the cheat code, enable the mod and click &amp;quot;Save&amp;quot; to compile the cheat codes.&lt;br /&gt;
&lt;br /&gt;
=== Using notepad or another editor ===&lt;br /&gt;
In your mod folder, create an empty text file, preferably called &amp;quot;Codes.lst&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Then open your mod.ini to add the following line:&lt;br /&gt;
 Codes=Codes.lst&lt;br /&gt;
Save your mod.ini, then open Codes.lst with the editor of your choice.&lt;br /&gt;
&lt;br /&gt;
Here is the structure of a cheat code:&lt;br /&gt;
 [Type] [Name] (Required)&lt;br /&gt;
 [Code]&lt;br /&gt;
 Author [Author]&lt;br /&gt;
 Category [Category]&lt;br /&gt;
 Description [Description]&lt;br /&gt;
Fields are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Type*&#039;&#039;&#039;: &amp;quot;Code&amp;quot; will make your cheat code run every frame, &amp;quot;Patch&amp;quot; will make it run once at start up.&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: short name for the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Required&#039;&#039;&#039;: the cheat code will be forced on and won&#039;t appear in the Mod Manager &amp;quot;Codes&amp;quot; tab.&lt;br /&gt;
* &#039;&#039;&#039;Code&#039;&#039;&#039;: the actual code, see [[Creating mods/Cheat Codes#Writing a cheat code|Writing a cheat code]].&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;, &#039;&#039;&#039;Category&#039;&#039;&#039; and &#039;&#039;&#039;Description&#039;&#039;&#039; are optional.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the Codes.lst file, open the Mod Manager, enable the mod if not already and click &amp;quot;Save&amp;quot; to compile the cheat codes.&lt;br /&gt;
&lt;br /&gt;
== Writing a cheat code ==&lt;br /&gt;
See the full [https://github.com/X-Hax/sadx-mod-loader/blob/master/doc/codes.md documentation].&lt;br /&gt;
&lt;br /&gt;
=== Memory operations ===&lt;br /&gt;
Each line follows the following format:&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
The memory operations you can use are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Write&lt;br /&gt;
|write8&lt;br /&gt;
write16&lt;br /&gt;
write32&lt;br /&gt;
writefloat&lt;br /&gt;
|Write value at address&lt;br /&gt;
|*address = value;&lt;br /&gt;
|-&lt;br /&gt;
|Add&lt;br /&gt;
|add8&lt;br /&gt;
add16&lt;br /&gt;
add32&lt;br /&gt;
addfloat&lt;br /&gt;
|Add value at address&lt;br /&gt;
|*address += value;&lt;br /&gt;
|-&lt;br /&gt;
|Subtract&lt;br /&gt;
|sub8&lt;br /&gt;
sub16&lt;br /&gt;
sub32&lt;br /&gt;
subfloat&lt;br /&gt;
|Subtract value at address&lt;br /&gt;
|*address -= value;&lt;br /&gt;
|-&lt;br /&gt;
|Multiply&lt;br /&gt;
|mulu8&lt;br /&gt;
mulu16&lt;br /&gt;
mulu32&lt;br /&gt;
muls8&lt;br /&gt;
muls16&lt;br /&gt;
muls32&lt;br /&gt;
mulfloat&lt;br /&gt;
|Multiply value at address&lt;br /&gt;
|*address *= value;&lt;br /&gt;
|-&lt;br /&gt;
|Divide&lt;br /&gt;
|divu8&lt;br /&gt;
divu16&lt;br /&gt;
divu32&lt;br /&gt;
divs8&lt;br /&gt;
divs16&lt;br /&gt;
divs32&lt;br /&gt;
divfloat&lt;br /&gt;
|Divide value at address&lt;br /&gt;
|*address /= value;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bitwise operations ===&lt;br /&gt;
These are more advanced operations as they operate on the bit level.&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Shift left&lt;br /&gt;
|shl8&lt;br /&gt;
shl16&lt;br /&gt;
shl32&lt;br /&gt;
|Shift bits at address to the left&lt;br /&gt;
|*address &amp;lt;&amp;lt;= value;&lt;br /&gt;
|-&lt;br /&gt;
|Shift right&lt;br /&gt;
|shrs8&lt;br /&gt;
shrs16&lt;br /&gt;
shrs32&lt;br /&gt;
shru8&lt;br /&gt;
shru16&lt;br /&gt;
shru32&lt;br /&gt;
|Shift bits at address to the right&lt;br /&gt;
|*address &amp;gt;&amp;gt;= value;&lt;br /&gt;
|-&lt;br /&gt;
|AND&lt;br /&gt;
|and8&lt;br /&gt;
and16&lt;br /&gt;
and32&lt;br /&gt;
|AND bits at address&lt;br /&gt;
Often used to remove flags&lt;br /&gt;
|*address &amp;amp;= value;&lt;br /&gt;
|-&lt;br /&gt;
|OR&lt;br /&gt;
|or8&lt;br /&gt;
or16&lt;br /&gt;
or32&lt;br /&gt;
|OR bits at address&lt;br /&gt;
Often used to add flags&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;*address |= value;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|XOR&lt;br /&gt;
|xor8&lt;br /&gt;
xor16&lt;br /&gt;
xor32&lt;br /&gt;
|XOR bits at address&lt;br /&gt;
|*address ^= value;&lt;br /&gt;
|-&lt;br /&gt;
|Rotate left&lt;br /&gt;
|rol8&lt;br /&gt;
rol16&lt;br /&gt;
rol32&lt;br /&gt;
|Rotate bits left&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Rotate right&lt;br /&gt;
|ror8&lt;br /&gt;
ror16&lt;br /&gt;
ror32&lt;br /&gt;
|Rotate bits right&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Special operations ===&lt;br /&gt;
 [opcode] [address] [value]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Write NOP&lt;br /&gt;
|writenop&lt;br /&gt;
|Write NOP opcode at address N times&lt;br /&gt;
Often used to remove a call (writenop address 5)&lt;br /&gt;
|WriteData&amp;lt;value&amp;gt;((void*)address, 0x90);&lt;br /&gt;
|-&lt;br /&gt;
|Write JUMP&lt;br /&gt;
|writejump&lt;br /&gt;
|Write a JUMP opcode at address followed by rel jump address&lt;br /&gt;
Often used to redirect a function to another&lt;br /&gt;
|WriteJump((void*)address, (void*)value);&lt;br /&gt;
|-&lt;br /&gt;
|Write CALL&lt;br /&gt;
|writecall&lt;br /&gt;
|Write a CALL opcode at address followed by rel call address&lt;br /&gt;
Often used to replace a call to a function with another&lt;br /&gt;
|WriteCall((void*)address, (void*)value);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
The cheat code system supports conditions and branching.&lt;br /&gt;
 [condition opcode] [address] [compared value] (repeat count)&lt;br /&gt;
 	...&lt;br /&gt;
 &#039;&#039;else&lt;br /&gt;
 	...&#039;&#039;&lt;br /&gt;
 endif&lt;br /&gt;
Here are the conditions available:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|If equal&lt;br /&gt;
|ifeq8&lt;br /&gt;
ifeq16&lt;br /&gt;
ifeq32&lt;br /&gt;
ifeqfloat&lt;br /&gt;
|Check if value at address is equal&lt;br /&gt;
|if (*address == value)&lt;br /&gt;
|-&lt;br /&gt;
|If not equal&lt;br /&gt;
|ifne8&lt;br /&gt;
ifne16&lt;br /&gt;
ifne32&lt;br /&gt;
ifnefloat&lt;br /&gt;
|Check if value at address is different&lt;br /&gt;
|if (*address != value)&lt;br /&gt;
|-&lt;br /&gt;
|If lower&lt;br /&gt;
|ifltu8&lt;br /&gt;
ifltu16&lt;br /&gt;
ifltu32&lt;br /&gt;
iflts8&lt;br /&gt;
iflts16&lt;br /&gt;
iflts32&lt;br /&gt;
ifltfloat&lt;br /&gt;
|Check if value at address is lower&lt;br /&gt;
|if (*address &amp;lt; value)&lt;br /&gt;
|-&lt;br /&gt;
|If lower or equal&lt;br /&gt;
|ifltequ8&lt;br /&gt;
ifltequ16&lt;br /&gt;
ifltequ32&lt;br /&gt;
iflteqs8&lt;br /&gt;
iflteqs16&lt;br /&gt;
iflteqs32&lt;br /&gt;
iflteqfloat&lt;br /&gt;
|Check if value at address is lower or equal&lt;br /&gt;
|if (*address &amp;lt;= value)&lt;br /&gt;
|-&lt;br /&gt;
|If greater&lt;br /&gt;
|ifgtu8&lt;br /&gt;
ifgtu16&lt;br /&gt;
ifgtu32&lt;br /&gt;
ifgts8&lt;br /&gt;
ifgts16&lt;br /&gt;
ifgts32&lt;br /&gt;
ifgtfloat&lt;br /&gt;
|Check if value at address is greater&lt;br /&gt;
|if (*address &amp;gt; value)&lt;br /&gt;
|-&lt;br /&gt;
|If greater or equal&lt;br /&gt;
|ifgtequ8&lt;br /&gt;
ifgtequ16&lt;br /&gt;
ifgtequ32&lt;br /&gt;
ifgteqs8&lt;br /&gt;
ifgteqs16&lt;br /&gt;
ifgteqs32&lt;br /&gt;
ifgteqfloat&lt;br /&gt;
|Check if value at address is greater or equal&lt;br /&gt;
|if (*address &amp;gt;= value)&lt;br /&gt;
|-&lt;br /&gt;
|If mask&lt;br /&gt;
|ifmask8&lt;br /&gt;
ifmask16&lt;br /&gt;
ifmask32&lt;br /&gt;
|Check if value at address has specific bits&lt;br /&gt;
Often used to check flags&lt;br /&gt;
|if ((*address &amp;amp; value) == value)&lt;br /&gt;
|-&lt;br /&gt;
|If key pressed&lt;br /&gt;
|ifkbkey [keycode]&lt;br /&gt;
|Check if keyboard key is pressed&lt;br /&gt;
See Windows [https://learn.microsoft.com/fr-fr/windows/win32/inputdev/virtual-key-codes virtual key codes].&lt;br /&gt;
|if (GetAsyncKeyState(value))&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Registers ===&lt;br /&gt;
The cheat code system has 16 registers available, you can use them as variables.&lt;br /&gt;
&lt;br /&gt;
Most opcodes have a register equivalent, simply add &amp;quot;reg&amp;quot; before the type (writereg8, divregu8, ifmaskreg8...)&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Read&lt;br /&gt;
|readreg8&lt;br /&gt;
readreg16&lt;br /&gt;
readreg32&lt;br /&gt;
|Read value at address into register&lt;br /&gt;
|reg[value] = *address;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Values format ===&lt;br /&gt;
Values can be in decimal, hexadecimal, or float format.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Example&lt;br /&gt;
|-&lt;br /&gt;
|Decimal&lt;br /&gt;
|10&lt;br /&gt;
|-&lt;br /&gt;
|Hexadecimal&lt;br /&gt;
|0xA&lt;br /&gt;
|-&lt;br /&gt;
|Float&lt;br /&gt;
|10.0&lt;br /&gt;
|}&lt;br /&gt;
Repeat count should be preceded with x.&lt;br /&gt;
&lt;br /&gt;
Addresses can be in hexadecimal or pointer chain format.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Example&lt;br /&gt;
|-&lt;br /&gt;
|Hexadecimal&lt;br /&gt;
|03B0F0FC&lt;br /&gt;
|-&lt;br /&gt;
|Pointer chain&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;p03B42E30|20|C0|6&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
These examples use Sonic Adventure DX (2004) addresses.&lt;br /&gt;
&lt;br /&gt;
=== Write to memory ===&lt;br /&gt;
 write16 03B0F0E4 999&lt;br /&gt;
This forces the ring count to 999 every frame.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;write16&amp;lt;/code&amp;gt; means that it will write to 2 bytes. This is because the Rings variable in SADX is a 2 bytes (a &amp;quot;short&amp;quot; or &amp;quot;Sint16&amp;quot; in c++).&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F0E4&amp;lt;/code&amp;gt; is the hexadecimal address of the Rings variable&lt;br /&gt;
* &amp;lt;code&amp;gt;999&amp;lt;/code&amp;gt; is the 2-byte values that is going to be written at the provided address.&lt;br /&gt;
&lt;br /&gt;
 writefloat 03B0F0FC 1.0&lt;br /&gt;
This forces the gravity to be upside down.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;writefloat&amp;lt;/code&amp;gt; means that the edited value is a (single precision) floating point value.&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F0FC&amp;lt;/code&amp;gt; is the hexadecimal address of the up gravity direction.&lt;br /&gt;
* &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is a float value that we will be writing, 1.0 for up gravity means upward.&lt;br /&gt;
&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
 ifltu32 03B0F14C 9999&lt;br /&gt;
 	add32 03B0F14C 1&lt;br /&gt;
 endif&lt;br /&gt;
This increased the score counter every frame until it reaches 9999.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ifltu32&amp;lt;/code&amp;gt; means &amp;quot;if value is inferior to3 (9999 here)&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F14C&amp;lt;/code&amp;gt; is the level score.&lt;br /&gt;
&lt;br /&gt;
 ifmask32 03B0E9D0 0x10&lt;br /&gt;
 	mulfloat 03B0F0FC 1.05&lt;br /&gt;
 endif&lt;br /&gt;
This increases the gravity when you press d-pad up.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ifmask32&amp;lt;/code&amp;gt; means we are checking if the value at address has specific bits&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0E9D0&amp;lt;/code&amp;gt; is the hexadecimal address of the pressed buttons variable, each bit corresponds to a button.&lt;br /&gt;
* &amp;lt;code&amp;gt;0x10&amp;lt;/code&amp;gt; is the bit mask for d-pad up.&lt;br /&gt;
&lt;br /&gt;
=== More examples ===&lt;br /&gt;
Check the [https://github.com/X-Hax/sadx-mod-loader/blob/master/data/Codes.lst SADX Mod Loader cheat codes] and [https://github.com/X-Hax/sa2-mod-loader/blob/master/data/Codes.lst SA2 Mod Loader cheat codes] for more examples.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
To get addresses:&lt;br /&gt;
&lt;br /&gt;
* Check the RAM editing pages on sonicretro ([https://info.sonicretro.org/SCHG:Sonic_Adventure_DX:_PC/RAM_Editing SADX]/[https://info.sonicretro.org/SCHG:Sonic_Adventure_2_(PC)/RAM_Editing SA2PC])&lt;br /&gt;
* Start disassembling the game with IDA Pro or Ghidra&lt;br /&gt;
* Ask us for help on Discord&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Cheat_Codes&amp;diff=285</id>
		<title>Creating Mods/Cheat Codes</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Cheat_Codes&amp;diff=285"/>
		<updated>2025-10-05T20:27:43Z</updated>

		<summary type="html">&lt;p&gt;Kell: Initial draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Sonic Adventure DX and Sonic Adventure 2: Battle Mod Loaders allow you to edit the game&#039;s code and memory without resorting to a DLL mod. The syntax is similar to cheat code for consoles, such as Action Replay code. This is useful for simple modifications where a DLL would be overkill.&lt;br /&gt;
&lt;br /&gt;
== Creating a cheat code ==&lt;br /&gt;
&lt;br /&gt;
=== Using the SA Mod Manager ===&lt;br /&gt;
First edit your mod by right clicking it and clicking on Edit mod, or by selecting it and pressing Ctrl + E.&lt;br /&gt;
[[File:Samm-editmod-context.png|none|508x508px]]&lt;br /&gt;
Then go in the &amp;quot;Codes&amp;quot; tab and click on &amp;quot;New code&amp;quot;.&lt;br /&gt;
[[File:Samm-editmode-codestab.png|none|502x502px]]&lt;br /&gt;
You are now in the cheat code editor :&lt;br /&gt;
[[File:Samm-editmode-codeeditor.png|none|500x500px]]&lt;br /&gt;
Fields are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: short name for the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: author(s) of the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Type*&#039;&#039;&#039;: &amp;quot;Code&amp;quot; will make your cheat code run every frame, &amp;quot;Patch&amp;quot; will make it run once at start up.&lt;br /&gt;
* &#039;&#039;&#039;Is Required&#039;&#039;&#039;: if checked, the cheat code will be forced on and won&#039;t appear in the Mod Manager &amp;quot;Codes&amp;quot; tab.&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: description of the cheat code.&lt;br /&gt;
&lt;br /&gt;
To write the code, see Writing a cheat code.&lt;br /&gt;
&lt;br /&gt;
When finished, save the cheat code, enable the mod and click &amp;quot;Save&amp;quot; to compile the cheat codes.&lt;br /&gt;
&lt;br /&gt;
=== Using notepad or another editor ===&lt;br /&gt;
In your mod folder, create an empty text file, preferably called &amp;quot;Codes.lst&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Then open your mod.ini to add the following line:&lt;br /&gt;
 Codes=Codes.lst&lt;br /&gt;
Save your mod.ini, then open Codes.lst with the editor of your choice.&lt;br /&gt;
&lt;br /&gt;
Here is the structure of a cheat code:&lt;br /&gt;
 [Type] [Name] (Required)&lt;br /&gt;
 [Code]&lt;br /&gt;
 Author [Author]&lt;br /&gt;
 Category [Category]&lt;br /&gt;
 Description [Description]&lt;br /&gt;
Fields are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Type*&#039;&#039;&#039;: &amp;quot;Code&amp;quot; will make your cheat code run every frame, &amp;quot;Patch&amp;quot; will make it run once at start up.&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: short name for the cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Required&#039;&#039;&#039;: the cheat code will be forced on and won&#039;t appear in the Mod Manager &amp;quot;Codes&amp;quot; tab.&lt;br /&gt;
* &#039;&#039;&#039;Code&#039;&#039;&#039;: the actual code, see Writing a cheat code.&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;, &#039;&#039;&#039;Category&#039;&#039;&#039; and &#039;&#039;&#039;Description&#039;&#039;&#039; are optional.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the Codes.lst file, open the Mod Manager, enable the mod if not already and click &amp;quot;Save&amp;quot; to compile the cheat codes.&lt;br /&gt;
&lt;br /&gt;
== Writing a cheat code ==&lt;br /&gt;
See the full [https://github.com/X-Hax/sadx-mod-loader/blob/master/doc/codes.md documentation].&lt;br /&gt;
&lt;br /&gt;
=== Memory operations ===&lt;br /&gt;
Each line follows the following format:&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
The memory operations you can use are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Write&lt;br /&gt;
|write8&lt;br /&gt;
write16&lt;br /&gt;
write32&lt;br /&gt;
writefloat&lt;br /&gt;
|Write value at address&lt;br /&gt;
|*address = value;&lt;br /&gt;
|-&lt;br /&gt;
|Add&lt;br /&gt;
|add8&lt;br /&gt;
add16&lt;br /&gt;
add32&lt;br /&gt;
addfloat&lt;br /&gt;
|Add value at address&lt;br /&gt;
|*address += value;&lt;br /&gt;
|-&lt;br /&gt;
|Subtract&lt;br /&gt;
|sub8&lt;br /&gt;
sub16&lt;br /&gt;
sub32&lt;br /&gt;
subfloat&lt;br /&gt;
|Subtract value at address&lt;br /&gt;
|*address -= value;&lt;br /&gt;
|-&lt;br /&gt;
|Multiply&lt;br /&gt;
|mulu8&lt;br /&gt;
mulu16&lt;br /&gt;
mulu32&lt;br /&gt;
muls8&lt;br /&gt;
muls16&lt;br /&gt;
muls32&lt;br /&gt;
mulfloat&lt;br /&gt;
|Multiply value at address&lt;br /&gt;
|*address *= value;&lt;br /&gt;
|-&lt;br /&gt;
|Divide&lt;br /&gt;
|divu8&lt;br /&gt;
divu16&lt;br /&gt;
divu32&lt;br /&gt;
divs8&lt;br /&gt;
divs16&lt;br /&gt;
divs32&lt;br /&gt;
divfloat&lt;br /&gt;
|Divide value at address&lt;br /&gt;
|*address /= value;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bitwise operations ===&lt;br /&gt;
These are more advanced operations as they operate on the bit level.&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Shift left&lt;br /&gt;
|shl8&lt;br /&gt;
shl16&lt;br /&gt;
shl32&lt;br /&gt;
|Shift bits at address to the left&lt;br /&gt;
|*address &amp;lt;&amp;lt;= value;&lt;br /&gt;
|-&lt;br /&gt;
|Shift right&lt;br /&gt;
|shrs8&lt;br /&gt;
shrs16&lt;br /&gt;
shrs32&lt;br /&gt;
shru8&lt;br /&gt;
shru16&lt;br /&gt;
shru32&lt;br /&gt;
|Shift bits at address to the right&lt;br /&gt;
|*address &amp;gt;&amp;gt;= value;&lt;br /&gt;
|-&lt;br /&gt;
|AND&lt;br /&gt;
|and8&lt;br /&gt;
and16&lt;br /&gt;
and32&lt;br /&gt;
|AND bits at address&lt;br /&gt;
Often used to remove flags&lt;br /&gt;
|*address &amp;amp;= value;&lt;br /&gt;
|-&lt;br /&gt;
|OR&lt;br /&gt;
|or8&lt;br /&gt;
or16&lt;br /&gt;
or32&lt;br /&gt;
|OR bits at address&lt;br /&gt;
Often used to add flags&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;*address |= value;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|XOR&lt;br /&gt;
|xor8&lt;br /&gt;
xor16&lt;br /&gt;
xor32&lt;br /&gt;
|XOR bits at address&lt;br /&gt;
|*address ^= value;&lt;br /&gt;
|-&lt;br /&gt;
|Rotate left&lt;br /&gt;
|rol8&lt;br /&gt;
rol16&lt;br /&gt;
rol32&lt;br /&gt;
|Rotate bits left&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Rotate right&lt;br /&gt;
|ror8&lt;br /&gt;
ror16&lt;br /&gt;
ror32&lt;br /&gt;
|Rotate bits right&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Special operations ===&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Write NOP&lt;br /&gt;
|writenop&lt;br /&gt;
|Write NOP opcode at address N times&lt;br /&gt;
Often used to remove a call (writenop address 5)&lt;br /&gt;
|WriteData&amp;lt;value&amp;gt;((void*)address, 0x90);&lt;br /&gt;
|-&lt;br /&gt;
|Write JUMP&lt;br /&gt;
|writejump&lt;br /&gt;
|Write a JUMP opcode at address followed by rel jump address&lt;br /&gt;
Often used to redirect a function to another&lt;br /&gt;
|WriteJump((void*)address, (void*)value);&lt;br /&gt;
|-&lt;br /&gt;
|Write CALL&lt;br /&gt;
|writecall&lt;br /&gt;
|Write a CALL opcode at address followed by rel call address&lt;br /&gt;
Often used to replace a call to a function with another&lt;br /&gt;
|WriteCall((void*)address, (void*)value);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
The cheat code system supports conditions and branching.&lt;br /&gt;
 [condition opcode] [address] [compared value] (repeat count)&lt;br /&gt;
 	...&lt;br /&gt;
 &#039;&#039;else&lt;br /&gt;
 	...&#039;&#039;&lt;br /&gt;
 endif&lt;br /&gt;
Here are the conditions available:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|If equal&lt;br /&gt;
|ifeq8&lt;br /&gt;
ifeq16&lt;br /&gt;
ifeq32&lt;br /&gt;
ifeqfloat&lt;br /&gt;
|Check if value at address is equal&lt;br /&gt;
|if (*address == value)&lt;br /&gt;
|-&lt;br /&gt;
|If not equal&lt;br /&gt;
|ifne8&lt;br /&gt;
ifne16&lt;br /&gt;
ifne32&lt;br /&gt;
ifnefloat&lt;br /&gt;
|Check if value at address is different&lt;br /&gt;
|if (*address != value)&lt;br /&gt;
|-&lt;br /&gt;
|If lower&lt;br /&gt;
|ifltu8&lt;br /&gt;
ifltu16&lt;br /&gt;
ifltu32&lt;br /&gt;
iflts8&lt;br /&gt;
iflts16&lt;br /&gt;
iflts32&lt;br /&gt;
ifltfloat&lt;br /&gt;
|Check if value at address is lower&lt;br /&gt;
|if (*address &amp;lt; value)&lt;br /&gt;
|-&lt;br /&gt;
|If lower or equal&lt;br /&gt;
|ifltequ8&lt;br /&gt;
ifltequ16&lt;br /&gt;
ifltequ32&lt;br /&gt;
iflteqs8&lt;br /&gt;
iflteqs16&lt;br /&gt;
iflteqs32&lt;br /&gt;
iflteqfloat&lt;br /&gt;
|Check if value at address is lower or equal&lt;br /&gt;
|if (*address &amp;lt;= value)&lt;br /&gt;
|-&lt;br /&gt;
|If greater&lt;br /&gt;
|ifgtu8&lt;br /&gt;
ifgtu16&lt;br /&gt;
ifgtu32&lt;br /&gt;
ifgts8&lt;br /&gt;
ifgts16&lt;br /&gt;
ifgts32&lt;br /&gt;
ifgtfloat&lt;br /&gt;
|Check if value at address is greater&lt;br /&gt;
|if (*address &amp;gt; value)&lt;br /&gt;
|-&lt;br /&gt;
|If greater or equal&lt;br /&gt;
|ifgtequ8&lt;br /&gt;
ifgtequ16&lt;br /&gt;
ifgtequ32&lt;br /&gt;
ifgteqs8&lt;br /&gt;
ifgteqs16&lt;br /&gt;
ifgteqs32&lt;br /&gt;
ifgteqfloat&lt;br /&gt;
|Check if value at address is greater or equal&lt;br /&gt;
|if (*address &amp;gt;= value)&lt;br /&gt;
|-&lt;br /&gt;
|If mask&lt;br /&gt;
|ifmask8&lt;br /&gt;
ifmask16&lt;br /&gt;
ifmask32&lt;br /&gt;
|Check if value at address has specific bits&lt;br /&gt;
Often used to check flags&lt;br /&gt;
|if ((*address &amp;amp; value) == value)&lt;br /&gt;
|-&lt;br /&gt;
|If key pressed&lt;br /&gt;
|ifkbkey [keycode]&lt;br /&gt;
|Check if keyboard key is pressed&lt;br /&gt;
See Windows [https://learn.microsoft.com/fr-fr/windows/win32/inputdev/virtual-key-codes virtual key codes].&lt;br /&gt;
|if (GetAsyncKeyState(value))&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Registers ===&lt;br /&gt;
The cheat code system has 16 registers available, you can use them as variables.&lt;br /&gt;
&lt;br /&gt;
Most opcodes have a register equivalent, simply add &amp;quot;reg&amp;quot; before the type (writereg8, divregu8, ifmaskreg8...)&lt;br /&gt;
 [opcode] [address] [value] (repeat count)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Opcodes&lt;br /&gt;
!Description&lt;br /&gt;
!C equivalent&lt;br /&gt;
|-&lt;br /&gt;
|Read&lt;br /&gt;
|readreg8&lt;br /&gt;
readreg16&lt;br /&gt;
readreg32&lt;br /&gt;
|Read value at address into register&lt;br /&gt;
|reg[value] = *address;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Values format ===&lt;br /&gt;
Values can be in decimal, hexadecimal, or float format.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Example&lt;br /&gt;
|-&lt;br /&gt;
|Decimal&lt;br /&gt;
|10&lt;br /&gt;
|-&lt;br /&gt;
|Hexadecimal&lt;br /&gt;
|0xA&lt;br /&gt;
|-&lt;br /&gt;
|Float&lt;br /&gt;
|10.0&lt;br /&gt;
|}&lt;br /&gt;
Repeat count should be preceded with x.&lt;br /&gt;
&lt;br /&gt;
Addresses can be in hexadecimal or pointer chain format.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Example&lt;br /&gt;
|-&lt;br /&gt;
|Hexadecimal&lt;br /&gt;
|03B0F0FC&lt;br /&gt;
|-&lt;br /&gt;
|Pointer chain&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;p03B42E30|20|C0|6&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
These examples use Sonic Adventure DX (2004) addresses.&lt;br /&gt;
&lt;br /&gt;
=== Write to memory ===&lt;br /&gt;
 write16 03B0F0E4 999&lt;br /&gt;
This forces the ring count to 999 every frame.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;write16&amp;lt;/code&amp;gt; means that it will write to 2 bytes. This is because the Rings variable in SADX is a 2 bytes (a &amp;quot;short&amp;quot; or &amp;quot;Sint16&amp;quot; in c++).&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F0E4&amp;lt;/code&amp;gt; is the hexadecimal address of the Rings variable&lt;br /&gt;
* &amp;lt;code&amp;gt;999&amp;lt;/code&amp;gt; is the 2-byte values that is going to be written at the provided address.&lt;br /&gt;
&lt;br /&gt;
 writefloat 03B0F0FC 1.0&lt;br /&gt;
This forces the gravity to be upside down.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;writefloat&amp;lt;/code&amp;gt; means that the edited value is a (single precision) floating point value.&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F0FC&amp;lt;/code&amp;gt; is the hexadecimal address of the up gravity direction.&lt;br /&gt;
* &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is a float value that we will be writing, 1.0 for up gravity means upward.&lt;br /&gt;
&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
 ifltu32 03B0F14C 9999&lt;br /&gt;
 	add32 03B0F14C 1&lt;br /&gt;
 endif&lt;br /&gt;
This increased the score counter every frame until it reaches 9999.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ifltu32&amp;lt;/code&amp;gt; means &amp;quot;if value is inferior to3 (9999 here)&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0F14C&amp;lt;/code&amp;gt; is the level score.&lt;br /&gt;
&lt;br /&gt;
 ifmask32 03B0E9D0 0x10&lt;br /&gt;
 	mulfloat 03B0F0FC 1.05&lt;br /&gt;
 endif&lt;br /&gt;
This increases the gravity when you press d-pad up.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ifmask32&amp;lt;/code&amp;gt; means we are checking if the value at address has specific bits&lt;br /&gt;
* &amp;lt;code&amp;gt;03B0E9D0&amp;lt;/code&amp;gt; is the hexadecimal address of the pressed buttons variable, each bit corresponds to a button.&lt;br /&gt;
* &amp;lt;code&amp;gt;0x10&amp;lt;/code&amp;gt; is the bit mask for d-pad up.&lt;br /&gt;
&lt;br /&gt;
=== More examples ===&lt;br /&gt;
Check the [https://github.com/X-Hax/sadx-mod-loader/blob/master/data/Codes.lst SADX Mod Loader cheat codes] and [https://github.com/X-Hax/sa2-mod-loader/blob/master/data/Codes.lst SA2 Mod Loader cheat codes] for more examples.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
To get addresses:&lt;br /&gt;
&lt;br /&gt;
* Check the RAM editing pages on sonicretro ([https://info.sonicretro.org/SCHG:Sonic_Adventure_DX:_PC/RAM_Editing SADX]/[https://info.sonicretro.org/SCHG:Sonic_Adventure_2_(PC)/RAM_Editing SA2PC])&lt;br /&gt;
* Start disassembling the game with IDA Pro or Ghidra&lt;br /&gt;
* Ask us for help on Discord&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-editmode-codeeditor.png&amp;diff=239</id>
		<title>File:Samm-editmode-codeeditor.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-editmode-codeeditor.png&amp;diff=239"/>
		<updated>2025-10-05T11:06:10Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-editmode-codestab.png&amp;diff=238</id>
		<title>File:Samm-editmode-codestab.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-editmode-codestab.png&amp;diff=238"/>
		<updated>2025-10-05T11:04:47Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Samm-editmod-context.png&amp;diff=237</id>
		<title>File:Samm-editmod-context.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Samm-editmod-context.png&amp;diff=237"/>
		<updated>2025-10-05T11:01:46Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=227</id>
		<title>Creating Mods</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=227"/>
		<updated>2025-10-04T22:45:49Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are many ways to modify Sonic Adventure DX and Sonic Adventure 2: Battle on PC using the Mod Loaders, from basic file editing to powerful code injection.&lt;br /&gt;
&lt;br /&gt;
The first step is to create your mod using the [[Mod Managers|Mod Manager]]. This will create a folder in which you will be able to put your modifications without affecting the original game files or executable.&lt;br /&gt;
&lt;br /&gt;
From there, you will be able to do:&lt;br /&gt;
&lt;br /&gt;
* [[Creating mods/File replacement|File replacement]]&lt;br /&gt;
* [[Creating mods/Texture replacement|Texture replacement]]&lt;br /&gt;
* [[Creating mods/Cheat Codes|Cheat codes]]&lt;br /&gt;
* [[Creating mods/Code injection|Code injection]] (DLL mod)&lt;br /&gt;
* [[Creating mods/Automatic updates|Automatic updates]]&lt;br /&gt;
* [[Creating mods/Mod configuration|Mod configuration]]&lt;br /&gt;
&lt;br /&gt;
= Creating a mod =&lt;br /&gt;
To create a mod you need the SA Mod Manager with Sonic Adventure DX and/or Sonic Adventure 2: Battle set up.&lt;br /&gt;
&lt;br /&gt;
First open SA Mod Manager with the game of your choice and click on the &amp;quot;Add Mod&amp;quot; button in the Mods tab.&lt;br /&gt;
[[File:Add-mod-button.png|none|509x509px]]&lt;br /&gt;
Then select &amp;quot;New Mod (For Developers)&amp;quot;&lt;br /&gt;
[[File:Add-mod-prompt.png|none|500x500px]]&lt;br /&gt;
This opens the mod creation form.&lt;br /&gt;
&lt;br /&gt;
=== Mod Information ===&lt;br /&gt;
[[File:New-mod-form-info.png|none|600x600px]]&lt;br /&gt;
Here are the information requested (* is mandatory):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: the name of the mod&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: your nickname, it is acceptable to add co-authors separated with commas&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: short description of the mod, it appears below the mod list&lt;br /&gt;
* &#039;&#039;&#039;Version&#039;&#039;&#039;: a version number, preferably numbers and dots. A common way to represent version is &amp;quot;major.minor&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;DLL&#039;&#039;&#039;: for code injection, this is the name of the DLL with the extension (e.g. &amp;quot;my-mod.dll&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039;: one of the categories listed or none&lt;br /&gt;
* &#039;&#039;&#039;Mod ID*&#039;&#039;&#039;: a unique name for your mod that should not change, preferably without spaces (e.g. &amp;quot;game.author.modname&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Include Directories&#039;&#039;&#039;: this is used for codeless mod configuration&lt;br /&gt;
* &#039;&#039;&#039;Author URL&#039;&#039;&#039;: link to a page of your choice, ideally showcasing your mods (GameBanana or GitHub profile for example)&lt;br /&gt;
* &#039;&#039;&#039;Source Code URL&#039;&#039;&#039;: for code injection, link to the source code (GitHub repository for example)&lt;br /&gt;
&lt;br /&gt;
This should have created a folder with a system folder (for SADX) or a gd_PC folder (for SA2B), you can use these for [[file replacement]].&lt;br /&gt;
&lt;br /&gt;
=== Update information ===&lt;br /&gt;
[[File:New-mod-form-update.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Creating mods/Automatic updates|automatic updates]], it is generally filled out later.&lt;br /&gt;
&lt;br /&gt;
For GitHub:&lt;br /&gt;
&lt;br /&gt;
* Author and repo is the right part of the repository URL (e.g. myself/my-mod)&lt;br /&gt;
* Release Asset is the name of the zip file in the release (e.g. my-mod.7z)&lt;br /&gt;
&lt;br /&gt;
For GameBanana:&lt;br /&gt;
&lt;br /&gt;
* Mod ID is the number in the mod&#039;s page URL (e.g. 123456)&lt;br /&gt;
* Mod Type shouldn&#039;t be changed (legacy)&lt;br /&gt;
&lt;br /&gt;
For self hosted:&lt;br /&gt;
&lt;br /&gt;
* Update URL: path to mod folder root on a remote http server&lt;br /&gt;
* Changelog URL: path to changelog file (plain text)&lt;br /&gt;
&lt;br /&gt;
=== Cheat codes ===&lt;br /&gt;
[[File:New-mod-form-cheat.png|none|600x600px]]&lt;br /&gt;
This tab is for [[Creating mods/Cheat Codes|cheat codes]].&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
[[File:New-mod-form-dependencies.png|none|600x600px]]&lt;br /&gt;
This tab is for mod dependencies. If your mod absolutely relies on another mod to function properly, you should add it here. The mod manager will warn users if they lack a dependency.&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:New-mod-form-dependencies.png&amp;diff=226</id>
		<title>File:New-mod-form-dependencies.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:New-mod-form-dependencies.png&amp;diff=226"/>
		<updated>2025-10-04T22:35:43Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:New-mod-form-cheat.png&amp;diff=225</id>
		<title>File:New-mod-form-cheat.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:New-mod-form-cheat.png&amp;diff=225"/>
		<updated>2025-10-04T22:34:19Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:New-mod-form-update.png&amp;diff=224</id>
		<title>File:New-mod-form-update.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:New-mod-form-update.png&amp;diff=224"/>
		<updated>2025-10-04T22:22:35Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=223</id>
		<title>Creating Mods</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods&amp;diff=223"/>
		<updated>2025-10-04T17:22:13Z</updated>

		<summary type="html">&lt;p&gt;Kell: First draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are many ways to modify Sonic Adventure DX and Sonic Adventure 2: Battle on PC using the Mod Loaders, from basic file editing to powerful code injection.&lt;br /&gt;
&lt;br /&gt;
The first step is to create your mod using the [[Mod Managers|Mod Manager]]. This will create a folder in which you will be able to put your modifications without affecting the original game files or executable.&lt;br /&gt;
&lt;br /&gt;
From there, you will be able to do:&lt;br /&gt;
&lt;br /&gt;
* [[Creating mods/File replacement|File replacement]]&lt;br /&gt;
* [[Creating mods/Texture editing|Texture editing]]&lt;br /&gt;
* [[Creating mods/Cheat Codes|Cheat codes]]&lt;br /&gt;
* [[Creating mods/Code injection|Code injection]]&lt;br /&gt;
* [[Creating mods/Automatic updates|Automatic updates]]&lt;br /&gt;
* [[Creating mods/Mod configuration|Mod configuration]]&lt;br /&gt;
&lt;br /&gt;
= Creating a mod =&lt;br /&gt;
To create a mod you need the SA Mod Manager with Sonic Adventure DX and/or Sonic Adventure 2: Battle set up.&lt;br /&gt;
&lt;br /&gt;
First open SA Mod Manager with the game of your choice and click on the &amp;quot;Add Mod&amp;quot; button in the Mods tab.&lt;br /&gt;
[[File:Add-mod-button.png|none|509x509px]]&lt;br /&gt;
Then select &amp;quot;New Mod (For Developers)&amp;quot;&lt;br /&gt;
[[File:Add-mod-prompt.png|none|500x500px]]&lt;br /&gt;
This opens the mod creation form:&lt;br /&gt;
[[File:New-mod-form-info.png|none|600x600px]]&lt;br /&gt;
Here are the information requested (* is mandatory):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Name*&#039;&#039;&#039;: the name of the mod&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039;: your nickname, it is acceptable to add co-authors separated with commas&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: short description of the mod, it appears below the mod list&lt;br /&gt;
* &#039;&#039;&#039;Version&#039;&#039;&#039;: a version number, preferably numbers and dots. A common way to represent version is &amp;quot;major.minor&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;DLL&#039;&#039;&#039;: for code injection, this is the name of the DLL with the extension (e.g. &amp;quot;my-mod.dll&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039;: one of the categories listed or none&lt;br /&gt;
* &#039;&#039;&#039;Mod ID*&#039;&#039;&#039;: a unique name for your mod that should not change, preferably without spaces (e.g. &amp;quot;game.author.modname&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;Include Directories&#039;&#039;&#039;: this is used for codeless mod configuration&lt;br /&gt;
* &#039;&#039;&#039;Author URL&#039;&#039;&#039;: link to a page of your choice, ideally showcasing your mods (GameBanana or GitHub profile for example)&lt;br /&gt;
* &#039;&#039;&#039;Source Code URL&#039;&#039;&#039;: for code injection, link to the source code (GitHub repository for example)&lt;br /&gt;
&lt;br /&gt;
This should have created a folder with a system folder (for SADX) or a gd_PC folder (for SA2B), you can use these for [[file replacement]].&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:New-mod-form-info.png&amp;diff=222</id>
		<title>File:New-mod-form-info.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:New-mod-form-info.png&amp;diff=222"/>
		<updated>2025-10-04T16:49:30Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Add-mod-prompt.png&amp;diff=221</id>
		<title>File:Add-mod-prompt.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Add-mod-prompt.png&amp;diff=221"/>
		<updated>2025-10-04T16:46:26Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Add-mod-button.png&amp;diff=220</id>
		<title>File:Add-mod-button.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Add-mod-button.png&amp;diff=220"/>
		<updated>2025-10-04T16:45:19Z</updated>

		<summary type="html">&lt;p&gt;Kell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kell</name></author>
	</entry>
</feed>