Create a DLL Mod - X-Hax/SA2BModdingGuide GitHub Wiki

Introduction

Welcome to SA2 DLL modding!

Modding Sonic Adventure 2 through code can give you incredible control over the game, which can allow you to add new features, enemies, and more. The possibilities are endless! As an example of what you can do, current DLL mods have been able to overhaul physics for the entire sonic cast, have been able to modify and upgrade existing levels through music, texture, and geometry changes, and can be used to bring more modern sonic features (such as the boost!) to Sonic Adventure 2.

In this tutorial, you will learn how to get started on writing your very own SA2 DLL mod, and learn some of the basic features of the included libraries to get a better handle on manipulating the game.

Note: Some simple changes, such as changing level geometry or replacing assets can be done without writing code. Please visit the X-Hax Discord for more details.

Requirements

Before you can start, you will need to download and install Visual Studio Community.

When installing, make sure you choose "Desktop Development with c++" which will include the tools you will need.

image

Cloning the SA2 Mod Template

Once Visual Studio has downloaded, you can start by cloning the Sonic Adventure 2 Mod Template by opening Visual Studio, and clicking on "Clone a repository."

image

Once there, copy and paste the Sonic Adventure 2 Mod Template link into the text box, and hit 'Clone.'

image

After Visual Studio has downloaded the template, you can begin coding by opening the "Solution Explorer" tab on the left, opening the "Source Files" tab, and clicking "main.cpp."

image

You are now ready to code!

How to Code for Sonic Adventure

DLL mods work with 4 major functions:

  1. Init
    • Runs code when the game starts. Good for setting things up!
  1. OnFrame
    • Runs code every frame of the game. Good for physics mods, character manipulation, and more!
    • (Warning) This function will run very often, even while in menus and during other game states. So make sure to include plenty of checks, and try to move code into Init, OnInput, or OnControl if possible.
  1. OnInput
    • Runs code every time a user presses an input (even including unmapped inputs). Good for remapping controls or adding new abilities!
  1. OnControl
    • Runs code every time a user presses a mapped input. Good for changing sonics abilities!

Each function is optional, meaning you can choose which functions you would like to include and which ones to leave out.

Interfacing with the Game

The mod template comes built-in with many tools you can use to interface with Sonic Adventure 2, including optional libraries that allow you to edit anything from stages, to enemies, to the game itself, and the player.

How to Explore the Given Libraries

There are many tools available for interfacing with and modifying game elements, too many to list in this tutorial. So if you would like to explore, I recommend checking out the SA2 Code Snippets for examples on how to do common things.

If you are confused about something that is not a code snippet, or a function you do not understand, explore the code by using "Ctrl+Click" on anything you don't understand. For example, if I were confused on what a "LandTable" is, I could type it out, and Ctrl+Click into it. I would then be sent to a definition that explains it. Lots of code can be found in the included 'pch.h' file, so I recommend exploring your options by Ctrl+Clicking into that, and into any files that contains.

Most importantly, make sure to join the X-Hax Discord and leave plenty of code questions :)

HelperFunctions

HelperFunctions is an object that you get access to in the Init function, that excels at helping you set up things before levels or events start. For instance, HelperFunctions has a method called 'RegisterStartPosition' that can set Sonic's spawn point for a given level, including where you want multiplayer spawns to be.

Built-in Enumerations, Variables, and Methods

The included .h files give you access to many important enumerations and variables that allow you to interface with the game with ease. Simply type them in and begin to code!

'ScoreP1' is a built-in variable that keeps track of the player's current score, which you can add to or subtract from at any time. The mod template by default adds 100 points every frame so you can see if your mod is working.

'GameState' is a built-in variable that signifies what state the game is in, whether it is in a level, in a menu, or if a 'levelRestart' just started. GameState comes with its own enumeration, meaning you can change the GameState by writing out one of many given GameStates. For example, if you wanted to kill sonic (good for setting up simple death zones), you can write this simple script:

if (sonic does something bad) {
   GameState = GameStates_NormalRestart;
}

'CurrentLevel' is built-in variable that signifies what level is currently loaded. Great for if statements! Also comes with its own enumeration for ease of use.

// Free points for playing City Escape!
if (CurrentLevel == LevelIDs_CityEscape) {
   ScoreP1 += 1000;
}

'MainCharObj1, MainCharObj2, and MainCharData2' are built-in variables that represents the current playable character(s). You can use this to get current position, speed, etc. These objects usually come in pointer form, so to access player 1, you need to specify an index.

// Get player 1's y position
MainCharObj1[0]->position.y

Find and Ctrl+Click into 'SAModLoader.h' and 'SA2Enums.h,' 'SA2Structs.h,' and 'SA2Variables.h' for more information!

Building your Mod

Once you've added a feature or some code that you would like to now try out, you can build your code by setting your build to 'Release x86,' and clicking "Build -> Build my-mod" or by pressing Ctrl+B on your keyboard.

image

image

Note: There should be no difference between 'Build' and 'Build Solution.'

Deploying your code

Before you deploy your code, it is important to set up your mod folder. The template comes with a prebuilt "Example Mod Folder," so to start, make sure you click and drag that into your SA2 Install, inside of the "mods" folder. Once you do that, feel free to change the name, and edit the mod.ini to better fit your mod.

Once you've built your code, it will compile and build a DLL in your 'Release' folder, along with some other files. The DLL file is the only file you need, so to deploy your code, all you need to do is simply drag and drop that DLL file into the mod folder you set up. For a simpler work flow, I recommend keeping a shortcut to your mod folder in your 'Release' folder, so that deploying your code is much easier.

Playing your mod

Once you've setup a mod folder and deployed your code, all that's left to do is play it! So open the Sonic Adventure 2 Mod Manager, enable your mod, hit 'Save,' and play! If the game crashes, double check your code, and if all else fails, visit the X-Hax Discord for troubleshooting help.

One common problem is file structure inside of your mod folder. Here are a few things to check:

  • Make sure the DLL name is the same as the DLL name specified in the mod.ini.
  • Make sure any assets used by your mod are in the correct places. (Most assets need to be put into a "gd_PC" folder inside of your mod, and texture paks need to be in "gd_PC/PRS")
  • Some mods can conflict with eachother, so if all else fails, try disabling all other mods but yours for testing.

Publishing your mod

There are many ways to share mods with friends, but one of the best ways is to upload the mod to the Sonic Adventure 2 Game Banana. Just make sure your mod works before uploading!

Happy modding!

(Old Tutorial) Manually setup your own project

  1. Click on "Create a new project" on the starting page. If there's no starting page, click on "File" then "New project".

Example of step 1

  1. Select the Dynamic Link Library template

Example of step 2

  1. Choose a name and a location for your project.

Example of step 3

Navigate to the location you've chose for the project.

  • The folder where the .sln file is is called the solution folder.
  • The subfolder containing the .vcxproj files is called the project folder.

3. Set up the mod loader includes

The Mod Loader includes contain the location of a lot of SA2 functions and variables.

  1. Open the programming folder that is shipped with the Mod Loader.
  2. Copy all files in that folder into your project folder.
  3. In Visual Studio, open pch.h (or stdafx.h for older visual studio), and add #include "SA2ModLoader.h".
  4. Build the solution ("Build" in the top panel -> "Build Solution") to check if it works.

If compilation fails be sure that:

  • You are compiling in x86 mode (top panel)
  • That in the properties of your project ("Project" -> "Properties") you are using an existing SDK and toolset.

If it still doesn't work, please tell us on Discord.

4. Adding in your own custom code.

Now that we have finished setting up our dll project, you can begin coding.

To do this, in Visual Studio, add a new cpp file in the "Source Files" filter.

Screenshot of how to add a cpp file to the Source Files filter

Name it whatever you'd like, and to start programming, copy and paste this basic boilerplate code:

#include "pch.h"
// or #include "stdafx.h" for previous Visual Studio versions

extern "C"
{
	__declspec(dllexport) void __cdecl Init(const char *path, const HelperFunctions &helperFunctions)
	{
		// Executed at startup, contains helperFunctions and the path to your mod (useful for getting the config file.)
		// This is where we override functions, replace static data, etc.
	}

	__declspec(dllexport) void __cdecl OnFrame()
	{
		// Executed every running frame of SA2
	}

	__declspec(dllexport) void __cdecl OnInput()
	{
		// Executed before the game processes input
	}

	__declspec(dllexport) void __cdecl OnControl()
	{
		// Executed when the game processes input
	}

	__declspec(dllexport) ModInfo SA2ModInfo = { ModLoaderVer }; // This is needed for the Mod Loader to recognize the DLL.
}

Notes: These functions are not all mandatory, and you can choose which you'd like to include in your mod. If you have experience programming with c++, you can treat the "Init" function like the main function, and your code will start executing from there. If your code needs to repeat, or is specific to game input, please use some of the other functions.

By default, the "Init" method runs when you first run the game.

If you would like to print any debug messages for easier development, use the "PrintDebug(char* message)" method, which is included from your pch.h.

Once you are done programming, you are ready to build your mod. To do this, go to "Build -> Build Solution," and in your file explorer, find your output near your project folder. You only need the dll, so you can ignore any other generated files.

To test if it works, you can add ScoreP1 += 1; in the "OnFrame" function and it will, every frame, increase the score by one.

5. Add our DLL to the mod folder

Now the last thing you need to do is add DLLFile=DLLNAME.dll to your mod.ini, and move the DLL into your mod folder. The DLL will be located in the Debug/Release folder at the root of your project folder. Don't forget to enable the mod in the Mod Manager!

Important: If you want to release your mod online, be sure to set the build mode (top panel) to Release!