<?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=ItsEasyActually</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=ItsEasyActually"/>
	<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/wiki/Special:Contributions/ItsEasyActually"/>
	<updated>2026-09-15T18:28:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=SADX_Mod_Loader&amp;diff=788</id>
		<title>SADX Mod Loader</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=SADX_Mod_Loader&amp;diff=788"/>
		<updated>2026-08-24T00:29:27Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: Updating page, adding Character Welds page link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can view the [https://github.com/X-Hax/sadx-mod-loader/ source code] here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On this page, you&#039;ll find documentation on the main API that the SADX Mod Loader exports to every code based mod created for SADX. There are additional features which are documented on other pages. You can follow the below links to find documentation on those features.&lt;br /&gt;
&lt;br /&gt;
[[SADX Mod Loader/Character Welds|Character Welds]]&lt;br /&gt;
= HelperFunctions API =&lt;br /&gt;
&lt;br /&gt;
== Struct ==&lt;br /&gt;
Below is the initialized version of the HelperFunctions struct. For the definition of the struct, you can find that in [https://github.com/X-Hax/sadx-mod-loader/blob/master/SADXModLoader/include/SADXModInfo.h SADXModInfo.h]&lt;br /&gt;
{{DocHeader|header=HelperFunctions|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
HelperFunctions helperFunctions =&lt;br /&gt;
{&lt;br /&gt;
	ModLoaderVer,&lt;br /&gt;
	&amp;amp;RegisterStartPosition,&lt;br /&gt;
	&amp;amp;ClearStartPositionList,&lt;br /&gt;
	&amp;amp;RegisterFieldStartPosition,&lt;br /&gt;
	&amp;amp;ClearFieldStartPositionList,&lt;br /&gt;
	&amp;amp;RegisterPathList,&lt;br /&gt;
	&amp;amp;ClearPathListList,&lt;br /&gt;
	&amp;amp;RegisterCharacterPVM,&lt;br /&gt;
	&amp;amp;ClearCharacterPVMList,&lt;br /&gt;
	&amp;amp;RegisterCommonObjectPVM,&lt;br /&gt;
	&amp;amp;ClearCommonObjectPVMList,&lt;br /&gt;
	&amp;amp;RegisterTrialLevel,&lt;br /&gt;
	&amp;amp;ClearTrialLevelList,&lt;br /&gt;
	&amp;amp;RegisterTrialSubgame,&lt;br /&gt;
	&amp;amp;ClearTrialSubgameList,&lt;br /&gt;
	&amp;amp;GetMainSavePath,&lt;br /&gt;
	&amp;amp;GetChaoSavePath,&lt;br /&gt;
	&amp;amp;GetReplaceablePath,&lt;br /&gt;
	&amp;amp;_ReplaceFile,&lt;br /&gt;
	&amp;amp;SetWindowTitle,&lt;br /&gt;
	&amp;amp;RegisterSoundList,&lt;br /&gt;
	&amp;amp;RegisterMusicFile,&lt;br /&gt;
	&amp;amp;LoadEXEData,&lt;br /&gt;
	&amp;amp;LoadDLLData,&lt;br /&gt;
	&amp;amp;_ReplaceFileForce,&lt;br /&gt;
	&amp;amp;PushScaleUI,&lt;br /&gt;
	&amp;amp;PopScaleUI,&lt;br /&gt;
	&amp;amp;SetScaleFillMode,&lt;br /&gt;
	&amp;amp;GetScaleFillMode,&lt;br /&gt;
	&amp;amp;ReplaceTexture,&lt;br /&gt;
	&amp;amp;MipmapBlacklistGBIX,&lt;br /&gt;
	&amp;amp;RegisterEnglishVoiceDuration,&lt;br /&gt;
	&amp;amp;RegisterJapaneseVoiceDuration,&lt;br /&gt;
	&amp;amp;RegisterCharacterWelds,&lt;br /&gt;
	&amp;amp;loaderSettings,&lt;br /&gt;
	&amp;amp;modList,&lt;br /&gt;
	&amp;amp;weightFuncs,&lt;br /&gt;
	&amp;amp;RegisterVoice,&lt;br /&gt;
	&amp;amp;PushInterpolationFix,&lt;br /&gt;
	&amp;amp;PopInterpolationFix,&lt;br /&gt;
	&amp;amp;RegisterPermanentTexlist,&lt;br /&gt;
	&amp;amp;ExpandPVMList,&lt;br /&gt;
	&amp;amp;UnreplaceFile,&lt;br /&gt;
	&amp;amp;PrintDebugUnicode,&lt;br /&gt;
	&amp;amp;PrintDebugLocal,&lt;br /&gt;
	&amp;amp;PrintDebugCodepage,&lt;br /&gt;
	&amp;amp;GetFileModIndex,&lt;br /&gt;
	&amp;amp;ReplaceFileAtIndex&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Note|text=Please be aware that all examples on this page will be using &amp;lt;code&amp;gt;helperFunctions&amp;lt;/code&amp;gt; which is how the variable is sent to a mod.|type=info}}&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
=== Mod Loader Version ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int ModLoaderVer;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This returns the version of the mod loader. This can be used to check if the user has an old version of the mod loader that may not have functionality your mod requires.&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
if (helperFunctions.ModLoaderVer &amp;lt;= 10)&lt;br /&gt;
    PrintDebug(&amp;quot;This Mod Loader is way out of date.\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Mod Loader Settings ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
LoaderSettings loaderSettings;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Mod List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;Mod&amp;gt; modlist;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Weight Functions ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
BasicWeightFuncs weightFuncs;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
== Functions ==&lt;br /&gt;
&lt;br /&gt;
=== Register Start Position ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterStartPosition(unsigned char character, const StartPosition&amp;amp; position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Registers a new Start Position for the specified character.&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
StartPosition myStageStartPos = { &lt;br /&gt;
    1,                          // Level ID &lt;br /&gt;
    0,                          // Act ID&lt;br /&gt;
    { 100.0f, 200.0f, 100.0f }, // Position&lt;br /&gt;
    0                           // Y Rotation&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// We pass our StagePosition variable as a pointer to this function&lt;br /&gt;
// and we have specified Sonic, so the level for this ID would now use&lt;br /&gt;
// our StartPosition instead of the original.&lt;br /&gt;
helperFunctions.RegisterStartPosition(Characters_Sonic, &amp;amp;myStageStartPos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Start Position List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearStartPositionList(unsigned char character)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clears the Start Positions for the specified character. &lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Running this inside of your mod&#039;s Init export would&lt;br /&gt;
// clear all of Sonic&#039;s Start Positions for his stages.&lt;br /&gt;
helperFunctions.ClearStartPositionList(Characters_Sonic);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Field Position ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterFieldStartPosition(unsigned char character, const FieldStartPosition&amp;amp; position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Field Start Position List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearFieldStartPositionList(unsigned char character)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Path List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterPathList(const PathDataPtr&amp;amp; paths)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Path List List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearPathListList()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Character PVM ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterCharacterPVM(unsigned char character, const PVMEntry&amp;amp; pvm)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Character PVM List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearCharacterPVMList(unsigned char character)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Common Object PVM ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterCommonObjectPVM(const PVMEntry&amp;amp; pvm)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Common Object PVM List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearCommonObjectPVMList()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Trial Level ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterTrialLevel(unsigned char character, const TrialLevelListEntry&amp;amp; level)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Trial Level List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearTrialLevelList(unsigned char character)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Trial Subgame ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void RegisterTrialSubgame(unsigned char character, const TrialLevelListEntry&amp;amp; level)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Clear Trial Subgame List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void ClearTrialSubgameList(unsigned char character)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Get Main Save Path ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static const char* GetMainSavePath()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Get Chao Save Path ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static const char* GetChaoSavePath()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Get Replaceable Path ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const char* __cdecl GetReplaceablePath(const char* path)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Replace File ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void _ReplaceFile(const char* src, const char* dst)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Set Window Title ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void SetWindowTitle(const char* title)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Sound List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int RegisterSoundList(const SoundList&amp;amp; list)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Music File ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int RegisterMusicFile(const MusicInfo&amp;amp; track)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Load EXE Data ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LoadEXEData(const wchar_t* filename, const wchar_t* mod_dir)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Load DLL Data ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LoadDLLData(const wchar_t* filename, const wchar_t* mod_dir)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Replace File Force ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void _ReplaceFileForce(const char* src, const char* dst)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Push Scale UI ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PushScaleUI(uiscale::Align align, bool is_background, float ratio_h, float ratio_v)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Pop Scale UI ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PopScaleUI()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Set Scale Fill Mode ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void SetScaleFillMode(uiscale::FillMode mode)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Get Scale Fill Mode ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
uiscale::FillMode GetScaleFillMode()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Replace Texture ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void ReplaceTexture(const char* pvm_name, const char* tex_name, const char* file_path, uint32_t gbix, uint32_t width, uint32_t height)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Mipmap Blacklist GBIX ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void MipmapBlacklistGBIX(Uint32 index)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register English Voice Duration ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void RegisterEnglishVoiceDuration(const uint16_t voiceID, const uint16_t duration)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Japanese Voice Duration ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void RegisterJapaneseVoiceDuration(const uint16_t voiceID, const uint16_t duration)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Character Welds ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void RegisterCharacterWelds(const uint8_t character, const char* iniPath)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Voice ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
uint16_t RegisterVoice(const char* fileJP, const char* fileEN, uint16_t durationJP, uint16_t durationEN)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Push Interpolation Fix ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PushInterpolationFix()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Pop Interpolation Fix ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PopInterpolationFix()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Register Permanent Texlist ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void RegisterPermanentTexlist(NJS_TEXLIST* texlist)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Unreplace File ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void UnreplaceFile(const char* file)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Expand PVM List ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TEX_PVMTABLE* ExpandPVMList(TEX_PVMTABLE* sourcepvmlist, const TEX_PVMTABLE &amp;amp;newpvmentry)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Unreplace File ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void UnreplaceFile(const char* file)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Print Debug Unicode ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PrintDebugUnicode(char* utf8)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Print Debug Local ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PrintDebugLocal(char* buf)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Print Debug Codepage ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void PrintDebugCodepage(char* buf, unsigned int source_cp)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Get File Mod Index ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int GetFileModIndex(const char* path)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Replace File At Index ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void ReplaceFileAtIndex(const char* src, const char* dst, int modIndex)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{DocHeader|header=Example|content=&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// TODO: Write example.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Mod_Configuration&amp;diff=786</id>
		<title>Creating Mods/Mod Configuration</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Mod_Configuration&amp;diff=786"/>
		<updated>2026-08-21T02:54:38Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: Adding images.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Mod Manager is capable of creating configuration files, saved as &amp;lt;code&amp;gt;config.ini&amp;lt;/code&amp;gt; in a mod folder, through a Mod Config system it has built in. This requires mods to supply a &amp;lt;code&amp;gt;configschema.xml&amp;lt;/code&amp;gt; within their mod folders. This is what defines the Groups, Properties, and custom Enumerations that can be used for creating a configuration file for a mod to make use of. &lt;br /&gt;
&lt;br /&gt;
If you&#039;re looking to create a codeless configuration system (it uses an in-built system in the mod loader for redirecting the system folders for loading), you can head over to the Codeless Configuration Setup section. &lt;br /&gt;
&lt;br /&gt;
If you want a more advanced system for Configuration that requires code, please check out the Code Configuration Setup section.&lt;br /&gt;
&lt;br /&gt;
== Config Schema ==&lt;br /&gt;
The Config Schema is an XML file that the Mod Manager will read from to generate the various elements used for a config file. Below is an example Config Schema followed by a break down on each element within a schema file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--Example Config Schema File--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ConfigSchema xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; xmlns=&amp;quot;http://www.sonicretro.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;Groups&amp;gt;&lt;br /&gt;
		&amp;lt;Group name=&amp;quot;config&amp;quot; display=&amp;quot;Configuration&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;speed&amp;quot; display=&amp;quot;Speed Value&amp;quot; type=&amp;quot;float&amp;quot; defaultvalue=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Sets the speed for a custom object.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
            &amp;lt;Property name=&amp;quot;object&amp;quot; display=&amp;quot;Object Type&amp;quot; type=&amp;quot;ObjectType&amp;quot; defaultvalue=&amp;quot;cub&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Sets the object model that is used.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;	&lt;br /&gt;
		&amp;lt;/Group&amp;gt;&lt;br /&gt;
	&amp;lt;/Groups&amp;gt;&lt;br /&gt;
	&amp;lt;Enums&amp;gt;&lt;br /&gt;
		&amp;lt;Enum name = &amp;quot;ObjectType&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;cub&amp;quot; display=&amp;quot;Cube&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sph&amp;quot; display=&amp;quot;Sphere&amp;quot; /&amp;gt;&lt;br /&gt;
            &amp;lt;EnumMember name=&amp;quot;cyl&amp;quot; display=&amp;quot;Cylinder&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
	&amp;lt;/Enums&amp;gt;&lt;br /&gt;
&amp;lt;/ConfigSchema&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
Groups are groupings of properties that will be saved to a configuration file. They are wrapped inside of a base &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element. All &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; elements must be placed inside of the &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element, just like how it is displayed in the example above.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This is the name that is written as the Group&#039;s name within the config file. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will overwrite the displayed name in the Editor within the Mod Manager which can make it easier for users to read. &lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
Properties are the actual variables written to a config file. These will always be wrapped inside of a &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; element.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: The name of the property that will be written to the config file. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will overwrite the name when displaying the property in the Mod Manager if it&#039;s included.&lt;br /&gt;
* &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;: The type of property this is. Below is a list of currently valid types supported by the Mod Manager and Mod Loaders. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
** &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt;: A boolean value. Valid values are &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;.&lt;br /&gt;
** &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;: An integer value. Valid values are any integer value.&lt;br /&gt;
** &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;: A floating point value. Valid values are any floating point value.&lt;br /&gt;
** &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;: A text value. Valid values are a string.&lt;br /&gt;
** &amp;lt;code&amp;gt;&amp;quot;enum&amp;quot;&amp;lt;/code&amp;gt;: Enum types need to match the name of the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; they correspond to. These are also the only supported type for Codeless Configuration. Valid values are the list of members of the specified &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type.&lt;br /&gt;
* &amp;lt;code&amp;gt;defaultvalue&amp;lt;/code&amp;gt;: This is the default value used by the property. It must be a valid value type for the supplied type. &#039;&#039;&#039;It is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;min&amp;lt;/code&amp;gt;: Optional value setting the minimum value. This is only used for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; types.&lt;br /&gt;
* &amp;lt;code&amp;gt;max&amp;lt;/code&amp;gt;: Optional value setting the maximum value. This is only used for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; types.&lt;br /&gt;
* &amp;lt;code&amp;gt;alwaysinclude&amp;lt;/code&amp;gt;: Optional boolean that, when set to true, forces the Manager to always write the property to the config file regardless of if it matches the default value or not.&lt;br /&gt;
&lt;br /&gt;
===== HelpText =====&lt;br /&gt;
The &amp;lt;code&amp;gt;HelpText&amp;lt;/code&amp;gt; element is used by a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; to supply a description or &amp;quot;helper&amp;quot; text to the user within the Mod Manager&#039;s editor. These are handled by doing.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HelpText&amp;gt;This is how the helper text should be written.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Please see the full Config Schema example above to see how these should be written within a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Enums ===&lt;br /&gt;
Just like with &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; elements being wrapped in a &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element, &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; elements are wrapped inside of an &amp;lt;code&amp;gt;Enums&amp;lt;/code&amp;gt; element. &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This sets the reference name to the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; within the Mod Manager&#039;s editor. This has no impact on the written config file, but &#039;&#039;&#039;it is still required.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== EnumMembers ====&lt;br /&gt;
These are the entries, or options, within an &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; that are utilized in the editor and are what get written to the config file when the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type is used in a property. Despite being sharing a name with enums, these are actually more like preset lists of strings that can be used.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This is what is written as the value for a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; making use of an &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will be displayed in the editor when supplied.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Note: While any text editor can be used for writing a Config Schema file, it&#039;s recommended to use one that supports writing XML, such as Notepad++ or VSCodium.&lt;br /&gt;
&lt;br /&gt;
== Codeless Configuration Setup ==&lt;br /&gt;
Codeless Configuration is an option for mod developers that want to include customizable asset replacement without needing to use code. As such, these are limited to &#039;&#039;solely&#039;&#039; asset replacement and have specific formatting that needs to be followed for the Mod Loader to correctly handle the asset loading redirection. They &#039;&#039;&#039;can&#039;&#039;&#039; be used in tandem with code mods that include other configuration options without the mod needing to implement its own custom asset redirection however.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
There are two ways to setup the prerequisites needed for Codeless Configuration; using the Mod Manager or editing &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually. Please follow the directions for the method you wish to use.&lt;br /&gt;
&lt;br /&gt;
==== Using the Mod Manager ====&lt;br /&gt;
In the Mod Manager, either create a new mod, use the Edit Mod option on an existing mod. This will open the Edit Mod window. In this window, locate the Include Directories entry. This is where you create the initial defaults and create the fallback folder IDs that will be stored inside the mod&#039;s &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; file. You can create multiple options for modifying different assets at the same time by separating each entry with a comma.&lt;br /&gt;
[[File:Example 1 for Codeless Configuration.png|center]]&lt;br /&gt;
In this example, the &amp;lt;code&amp;gt;sonic_sword&amp;lt;/code&amp;gt; option is for editing Sonic&#039;s model while the &amp;lt;code&amp;gt;altmusica&amp;lt;/code&amp;gt; would be for editing music files.&lt;br /&gt;
&lt;br /&gt;
==== Manually Adding Defaults ====&lt;br /&gt;
If you want to edit &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually so you can create the sub folders as you need them, simply open your mod&#039;s folder and open &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; in a text editor of your choice. You will then need to add a new Section named &amp;quot;Config.&amp;quot; Under this Section, you can create as many &amp;quot;Include Directories&amp;quot; as you need. These are formatted as &amp;lt;code&amp;gt;IncludeDirX&amp;lt;/code&amp;gt; where X is the ID number. These begin as index 0. You will also need to include an &amp;lt;code&amp;gt;IncludeDirCount&amp;lt;/code&amp;gt; which is the total number of directories you have setup. In our example, the following is how &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; looks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Name=Example Codeless Config&lt;br /&gt;
Author=ItsEasyActually&lt;br /&gt;
Version=0.1&lt;br /&gt;
ModID=sadx.ExampleCodelessConfig&lt;br /&gt;
[Config]&lt;br /&gt;
IncludeDir0=sonic_sword&lt;br /&gt;
IncludeDir1=altmusica&lt;br /&gt;
IncludeDirCount=2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Folder Structure ===&lt;br /&gt;
In your mod&#039;s folder, the default folders you just added should now be visible in the mod folder unless you modified &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually. This example will continue with the expectation that you have folders matching those examples.&lt;br /&gt;
[[File:Codeless Config Example 2.png|center]]&lt;br /&gt;
These sub folders act like a base mod folder which means they can contain any of the same folders a mod can contain, including the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; (SADX only)&lt;br /&gt;
* &amp;lt;code&amp;gt;gd_PC&amp;lt;/code&amp;gt; (SA2 only)&lt;br /&gt;
* &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacetex&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can also contain any of the exported INI files from the SA Tools, such as &amp;lt;code&amp;gt;sonic_data.ini&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sonic2app_data.ini&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The folders that were created are just the default folders as well. You can create additional folders to be used for these options which are how you get into having multiple options for asset replacement. &lt;br /&gt;
&lt;br /&gt;
For Codeless Config mods, the base &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;gd_PC&amp;lt;/code&amp;gt; in SA2), &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;replacetex&amp;lt;/code&amp;gt; folders are always loaded first if they exist (&#039;&#039;&#039;They are not required, just generated by default when making a mod with the Mod Manager&#039;&#039;&#039;). The Mod Loader will then load from any of the alternative directories (if valid) second. This allows users the option of having an &amp;quot;invalid&amp;quot; folder name as their default to only load from their base folders.&lt;br /&gt;
&lt;br /&gt;
==== Real World Example ====&lt;br /&gt;
The Sprite Rings mod for SADX is a good example of a real mod making use of this system. Below is a screenshot of that mod&#039;s folder:&lt;br /&gt;
[[File:Codeless Config Example 3.png|center]]&lt;br /&gt;
In this example, every folder (excluding &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;) contains a variation of sprite assets inside their own &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt; folders.&lt;br /&gt;
&lt;br /&gt;
The Sprite Rings mod for SADX also makes use of the &amp;quot;invalid&amp;quot; folder setup by labeling its default as &amp;lt;code&amp;gt;classic&amp;lt;/code&amp;gt; but no folder with that name actually exists. &lt;br /&gt;
&lt;br /&gt;
=== Creating the Config Schema ===&lt;br /&gt;
Creating a config schema to include the directory options is relatively straight forward. Properties can be stored inside of any &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; within the Config Schema files as the Mod Loader will search through all &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; looking for a matching property to the expected &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; name.&lt;br /&gt;
&lt;br /&gt;
The expected &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; names should match the variables setup in the mod&#039;s Config section of its &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; file, ie &amp;lt;code&amp;gt;IncludeDirX&amp;lt;/code&amp;gt; where X is the corresponding index. In our example, &amp;lt;code&amp;gt;sonic_sword&amp;lt;/code&amp;gt; is the default option for &amp;lt;code&amp;gt;IncludeDir0&amp;lt;/code&amp;gt; while &amp;lt;code&amp;gt;altmusica&amp;lt;/code&amp;gt; is the default option for &amp;lt;code&amp;gt;IncludeDir1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Making use of &amp;lt;code&amp;gt;Enums&amp;lt;/code&amp;gt; is the best way to setup the &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; types as it controls what the folder names are without the user needing to do anything further. The &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; field in an &amp;lt;code&amp;gt;EnumMember&amp;lt;/code&amp;gt; needs to match the folder name to work properly. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--Example Config Schema--&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ConfigSchema xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; xmlns=&amp;quot;http://www.sonicretro.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;Groups&amp;gt;&lt;br /&gt;
		&amp;lt;Group name=&amp;quot;options&amp;quot; display=&amp;quot;Example Options&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;IncludeDir0&amp;quot; type=&amp;quot;model&amp;quot; display=&amp;quot;Sonic Outfit&amp;quot; defaultvalue=&amp;quot;sonic_sword&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Select the outfit you want Sonic to use.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;IncludeDir1&amp;quot; type=&amp;quot;music&amp;quot; display=&amp;quot;Sonic Theme&amp;quot; defaultvalue=&amp;quot;altmusica&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Select the theme you want to be used for Sonic.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
		&amp;lt;/Group&amp;gt;&lt;br /&gt;
	&amp;lt;/Groups&amp;gt;&lt;br /&gt;
	&amp;lt;Enums&amp;gt;&lt;br /&gt;
		&amp;lt;Enum name=&amp;quot;model&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sonic_sword&amp;quot; display=&amp;quot;Sonic with Gauntlet (from SatBK)&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sonic_ring&amp;quot; display=&amp;quot;Sonic with Ring (from SatSR)&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;Enum name=&amp;quot;music&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;altmusica&amp;quot; display=&amp;quot;Knight of the Wind&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;altmusicb&amp;quot; display=&amp;quot;Seven Rings in Hand&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
	&amp;lt;/Enums&amp;gt;&lt;br /&gt;
&amp;lt;/ConfigSchema&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the end, this is how the overall folder looks after creating the Config Schema, adding the additional folder options, and removing the &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; folder as it was not needed:&lt;br /&gt;
[[File:Codeless Config Example 4.png|center]]&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
Default options inside the Config Schema should match the defaults within your mod&#039;s INI file. Failing to due so may result in unintended behavior where the Mod Loader will continue to load whatever the option set in the mod&#039;s INI is set to. This is because the Mod Loader checks for a &amp;lt;code&amp;gt;config.ini&amp;lt;/code&amp;gt; file and loads info from there. If it is not located, it sets the default directory to load as the one found in &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; as that is the fallback.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Code based Configuration Setup ==&lt;br /&gt;
&lt;br /&gt;
{{Note|text=This section will be added at a later date|type=info}}&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_4.png&amp;diff=785</id>
		<title>File:Codeless Config Example 4.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_4.png&amp;diff=785"/>
		<updated>2026-08-21T02:54:17Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Example of the final folder setup for the example mod for Codeless Config once all of the work has been done to set it up.&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_3.png&amp;diff=784</id>
		<title>File:Codeless Config Example 3.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_3.png&amp;diff=784"/>
		<updated>2026-08-21T02:53:25Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Real World example of Codeless Config taken from the Sprite Rings mod for SADX.&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_2.png&amp;diff=783</id>
		<title>File:Codeless Config Example 2.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Codeless_Config_Example_2.png&amp;diff=783"/>
		<updated>2026-08-21T02:52:30Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Example of the mod folder immediately after creating it from the Mod Manager.&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=File:Example_1_for_Codeless_Configuration.png&amp;diff=782</id>
		<title>File:Example 1 for Codeless Configuration.png</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=File:Example_1_for_Codeless_Configuration.png&amp;diff=782"/>
		<updated>2026-08-21T02:49:09Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Displays the Mod Manager Mod Editor window with Include Directories.&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
	<entry>
		<id>https://sadocs.unreliable.network/index.php?title=Creating_Mods/Mod_Configuration&amp;diff=781</id>
		<title>Creating Mods/Mod Configuration</title>
		<link rel="alternate" type="text/html" href="https://sadocs.unreliable.network/index.php?title=Creating_Mods/Mod_Configuration&amp;diff=781"/>
		<updated>2026-08-21T02:46:49Z</updated>

		<summary type="html">&lt;p&gt;ItsEasyActually: Initial publishing of this page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Mod Manager is capable of creating configuration files, saved as &amp;lt;code&amp;gt;config.ini&amp;lt;/code&amp;gt; in a mod folder, through a Mod Config system it has built in. This requires mods to supply a &amp;lt;code&amp;gt;configschema.xml&amp;lt;/code&amp;gt; within their mod folders. This is what defines the Groups, Properties, and custom Enumerations that can be used for creating a configuration file for a mod to make use of. &lt;br /&gt;
&lt;br /&gt;
If you&#039;re looking to create a codeless configuration system (it uses an in-built system in the mod loader for redirecting the system folders for loading), you can head over to the Codeless Configuration Setup section. &lt;br /&gt;
&lt;br /&gt;
If you want a more advanced system for Configuration that requires code, please check out the Code Configuration Setup section.&lt;br /&gt;
&lt;br /&gt;
== Config Schema ==&lt;br /&gt;
The Config Schema is an XML file that the Mod Manager will read from to generate the various elements used for a config file. Below is an example Config Schema followed by a break down on each element within a schema file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--Example Config Schema File--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ConfigSchema xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; xmlns=&amp;quot;http://www.sonicretro.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;Groups&amp;gt;&lt;br /&gt;
		&amp;lt;Group name=&amp;quot;config&amp;quot; display=&amp;quot;Configuration&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;speed&amp;quot; display=&amp;quot;Speed Value&amp;quot; type=&amp;quot;float&amp;quot; defaultvalue=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Sets the speed for a custom object.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
            &amp;lt;Property name=&amp;quot;object&amp;quot; display=&amp;quot;Object Type&amp;quot; type=&amp;quot;ObjectType&amp;quot; defaultvalue=&amp;quot;cub&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Sets the object model that is used.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;	&lt;br /&gt;
		&amp;lt;/Group&amp;gt;&lt;br /&gt;
	&amp;lt;/Groups&amp;gt;&lt;br /&gt;
	&amp;lt;Enums&amp;gt;&lt;br /&gt;
		&amp;lt;Enum name = &amp;quot;ObjectType&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;cub&amp;quot; display=&amp;quot;Cube&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sph&amp;quot; display=&amp;quot;Sphere&amp;quot; /&amp;gt;&lt;br /&gt;
            &amp;lt;EnumMember name=&amp;quot;cyl&amp;quot; display=&amp;quot;Cylinder&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
	&amp;lt;/Enums&amp;gt;&lt;br /&gt;
&amp;lt;/ConfigSchema&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
Groups are groupings of properties that will be saved to a configuration file. They are wrapped inside of a base &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element. All &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; elements must be placed inside of the &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element, just like how it is displayed in the example above.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This is the name that is written as the Group&#039;s name within the config file. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will overwrite the displayed name in the Editor within the Mod Manager which can make it easier for users to read. &lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
Properties are the actual variables written to a config file. These will always be wrapped inside of a &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; element.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: The name of the property that will be written to the config file. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will overwrite the name when displaying the property in the Mod Manager if it&#039;s included.&lt;br /&gt;
* &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;: The type of property this is. Below is a list of currently valid types supported by the Mod Manager and Mod Loaders. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
** &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt;: A boolean value. Valid values are &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;.&lt;br /&gt;
** &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;: An integer value. Valid values are any integer value.&lt;br /&gt;
** &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;: A floating point value. Valid values are any floating point value.&lt;br /&gt;
** &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt;: A text value. Valid values are a string.&lt;br /&gt;
** &amp;lt;code&amp;gt;&amp;quot;enum&amp;quot;&amp;lt;/code&amp;gt;: Enum types need to match the name of the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; they correspond to. These are also the only supported type for Codeless Configuration. Valid values are the list of members of the specified &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type.&lt;br /&gt;
* &amp;lt;code&amp;gt;defaultvalue&amp;lt;/code&amp;gt;: This is the default value used by the property. It must be a valid value type for the supplied type. &#039;&#039;&#039;It is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;min&amp;lt;/code&amp;gt;: Optional value setting the minimum value. This is only used for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; types.&lt;br /&gt;
* &amp;lt;code&amp;gt;max&amp;lt;/code&amp;gt;: Optional value setting the maximum value. This is only used for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; types.&lt;br /&gt;
* &amp;lt;code&amp;gt;alwaysinclude&amp;lt;/code&amp;gt;: Optional boolean that, when set to true, forces the Manager to always write the property to the config file regardless of if it matches the default value or not.&lt;br /&gt;
&lt;br /&gt;
===== HelpText =====&lt;br /&gt;
The &amp;lt;code&amp;gt;HelpText&amp;lt;/code&amp;gt; element is used by a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; to supply a description or &amp;quot;helper&amp;quot; text to the user within the Mod Manager&#039;s editor. These are handled by doing.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HelpText&amp;gt;This is how the helper text should be written.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Please see the full Config Schema example above to see how these should be written within a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Enums ===&lt;br /&gt;
Just like with &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; elements being wrapped in a &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; element, &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; elements are wrapped inside of an &amp;lt;code&amp;gt;Enums&amp;lt;/code&amp;gt; element. &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This sets the reference name to the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; within the Mod Manager&#039;s editor. This has no impact on the written config file, but &#039;&#039;&#039;it is still required.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== EnumMembers ====&lt;br /&gt;
These are the entries, or options, within an &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; that are utilized in the editor and are what get written to the config file when the &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type is used in a property. Despite being sharing a name with enums, these are actually more like preset lists of strings that can be used.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;: This is what is written as the value for a &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; making use of an &amp;lt;code&amp;gt;Enum&amp;lt;/code&amp;gt; type. &#039;&#039;&#039;This is required.&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;display&amp;lt;/code&amp;gt;: Optional name that will be displayed in the editor when supplied.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Note: While any text editor can be used for writing a Config Schema file, it&#039;s recommended to use one that supports writing XML, such as Notepad++ or VSCodium.&lt;br /&gt;
&lt;br /&gt;
== Codeless Configuration Setup ==&lt;br /&gt;
Codeless Configuration is an option for mod developers that want to include customizable asset replacement without needing to use code. As such, these are limited to &#039;&#039;solely&#039;&#039; asset replacement and have specific formatting that needs to be followed for the Mod Loader to correctly handle the asset loading redirection. They &#039;&#039;&#039;can&#039;&#039;&#039; be used in tandem with code mods that include other configuration options without the mod needing to implement its own custom asset redirection however.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
There are two ways to setup the prerequisites needed for Codeless Configuration; using the Mod Manager or editing &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually. Please follow the directions for the method you wish to use.&lt;br /&gt;
&lt;br /&gt;
==== Using the Mod Manager ====&lt;br /&gt;
In the Mod Manager, either create a new mod, use the Edit Mod option on an existing mod. This will open the Edit Mod window. In this window, locate the Include Directories entry. This is where you create the initial defaults and create the fallback folder IDs that will be stored inside the mod&#039;s &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; file. You can create multiple options for modifying different assets at the same time by separating each entry with a comma.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PICTURE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this example, the &amp;lt;code&amp;gt;sonic_sword&amp;lt;/code&amp;gt; option is for editing Sonic&#039;s model while the &amp;lt;code&amp;gt;altmusica&amp;lt;/code&amp;gt; would be for editing music files.&lt;br /&gt;
&lt;br /&gt;
==== Manually Adding Defaults ====&lt;br /&gt;
If you want to edit &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually so you can create the sub folders as you need them, simply open your mod&#039;s folder and open &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; in a text editor of your choice. You will then need to add a new Section named &amp;quot;Config.&amp;quot; Under this Section, you can create as many &amp;quot;Include Directories&amp;quot; as you need. These are formatted as &amp;lt;code&amp;gt;IncludeDirX&amp;lt;/code&amp;gt; where X is the ID number. These begin as index 0. You will also need to include an &amp;lt;code&amp;gt;IncludeDirCount&amp;lt;/code&amp;gt; which is the total number of directories you have setup. In our example, the following is how &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; looks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
Name=Example Codeless Config&lt;br /&gt;
Author=ItsEasyActually&lt;br /&gt;
Version=0.1&lt;br /&gt;
ModID=sadx.ExampleCodelessConfig&lt;br /&gt;
[Config]&lt;br /&gt;
IncludeDir0=sonic_sword&lt;br /&gt;
IncludeDir1=altmusica&lt;br /&gt;
IncludeDirCount=2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Folder Structure ===&lt;br /&gt;
In your mod&#039;s folder, the default folders you just added should now be visible in the mod folder unless you modified &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; manually. This example will continue with the expectation that you have folders matching those examples.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PICTURE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These sub folders act like a base mod folder which means they can contain any of the same folders a mod can contain, including the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; (SADX only)&lt;br /&gt;
* &amp;lt;code&amp;gt;gd_PC&amp;lt;/code&amp;gt; (SA2 only)&lt;br /&gt;
* &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacetex&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can also contain any of the exported INI files from the SA Tools, such as &amp;lt;code&amp;gt;sonic_data.ini&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sonic2app_data.ini&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The folders that were created are just the default folders as well. You can create additional folders to be used for these options which are how you get into having multiple options for asset replacement. &lt;br /&gt;
&lt;br /&gt;
For Codeless Config mods, the base &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;gd_PC&amp;lt;/code&amp;gt; in SA2), &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;replacetex&amp;lt;/code&amp;gt; folders are always loaded first if they exist (&#039;&#039;&#039;They are not required, just generated by default when making a mod with the Mod Manager&#039;&#039;&#039;). The Mod Loader will then load from any of the alternative directories (if valid) second. This allows users the option of having an &amp;quot;invalid&amp;quot; folder name as their default to only load from their base folders.&lt;br /&gt;
&lt;br /&gt;
==== Real World Example ====&lt;br /&gt;
The Sprite Rings mod for SADX is a good example of a real mod making use of this system. Below is a screenshot of that mod&#039;s folder:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PICTURE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this example, every folder (excluding &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt;) contains a variation of sprite assets inside their own &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt; folders.&lt;br /&gt;
&lt;br /&gt;
The Sprite Rings mod for SADX also makes use of the &amp;quot;invalid&amp;quot; folder setup by labeling its default as &amp;lt;code&amp;gt;classic&amp;lt;/code&amp;gt; but no folder with that name actually exists. &lt;br /&gt;
&lt;br /&gt;
=== Creating the Config Schema ===&lt;br /&gt;
Creating a config schema to include the directory options is relatively straight forward. Properties can be stored inside of any &amp;lt;code&amp;gt;Group&amp;lt;/code&amp;gt; within the Config Schema files as the Mod Loader will search through all &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; looking for a matching property to the expected &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; name.&lt;br /&gt;
&lt;br /&gt;
The expected &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; names should match the variables setup in the mod&#039;s Config section of its &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; file, ie &amp;lt;code&amp;gt;IncludeDirX&amp;lt;/code&amp;gt; where X is the corresponding index. In our example, &amp;lt;code&amp;gt;sonic_sword&amp;lt;/code&amp;gt; is the default option for &amp;lt;code&amp;gt;IncludeDir0&amp;lt;/code&amp;gt; while &amp;lt;code&amp;gt;altmusica&amp;lt;/code&amp;gt; is the default option for &amp;lt;code&amp;gt;IncludeDir1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Making use of &amp;lt;code&amp;gt;Enums&amp;lt;/code&amp;gt; is the best way to setup the &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; types as it controls what the folder names are without the user needing to do anything further. The &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; field in an &amp;lt;code&amp;gt;EnumMember&amp;lt;/code&amp;gt; needs to match the folder name to work properly. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--Example Config Schema--&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;ConfigSchema xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; xmlns=&amp;quot;http://www.sonicretro.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;Groups&amp;gt;&lt;br /&gt;
		&amp;lt;Group name=&amp;quot;options&amp;quot; display=&amp;quot;Example Options&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;IncludeDir0&amp;quot; type=&amp;quot;model&amp;quot; display=&amp;quot;Sonic Outfit&amp;quot; defaultvalue=&amp;quot;sonic_sword&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Select the outfit you want Sonic to use.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
			&amp;lt;Property name=&amp;quot;IncludeDir1&amp;quot; type=&amp;quot;music&amp;quot; display=&amp;quot;Sonic Theme&amp;quot; defaultvalue=&amp;quot;altmusica&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;HelpText&amp;gt;Select the theme you want to be used for Sonic.&amp;lt;/HelpText&amp;gt;&lt;br /&gt;
			&amp;lt;/Property&amp;gt;&lt;br /&gt;
		&amp;lt;/Group&amp;gt;&lt;br /&gt;
	&amp;lt;/Groups&amp;gt;&lt;br /&gt;
	&amp;lt;Enums&amp;gt;&lt;br /&gt;
		&amp;lt;Enum name=&amp;quot;model&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sonic_sword&amp;quot; display=&amp;quot;Sonic with Gauntlet (from SatBK)&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;sonic_ring&amp;quot; display=&amp;quot;Sonic with Ring (from SatSR)&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;Enum name=&amp;quot;music&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;altmusica&amp;quot; display=&amp;quot;Knight of the Wind&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;EnumMember name=&amp;quot;altmusicb&amp;quot; display=&amp;quot;Seven Rings in Hand&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/Enum&amp;gt;&lt;br /&gt;
	&amp;lt;/Enums&amp;gt;&lt;br /&gt;
&amp;lt;/ConfigSchema&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the end, this is how the overall folder looks after creating the Config Schema, adding the additional folder options, and removing the &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; folder as it was not needed:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PICTURE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Best Practices ===&lt;br /&gt;
Default options inside the Config Schema should match the defaults within your mod&#039;s INI file. Failing to due so may result in unintended behavior where the Mod Loader will continue to load whatever the option set in the mod&#039;s INI is set to. This is because the Mod Loader checks for a &amp;lt;code&amp;gt;config.ini&amp;lt;/code&amp;gt; file and loads info from there. If it is not located, it sets the default directory to load as the one found in &amp;lt;code&amp;gt;mod.ini&amp;lt;/code&amp;gt; as that is the fallback.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Code based Configuration Setup ==&lt;br /&gt;
&lt;br /&gt;
{{Note|text=This section will be added at a later date|type=info}}&lt;/div&gt;</summary>
		<author><name>ItsEasyActually</name></author>
	</entry>
</feed>