Getting Started

Mod Making Requirements

  • Windows Based Machine
  • Visual Studio 2019 Community Edition
    • The download will start shortly after visiting the game
    • Ensure you install (can always click modify and check / install):
    • Visual Studio Community 2019
      • .NET desktop development
      • Game development with Unity
    • Visual Studio Build Tools 2019
      • .NET dekstop build tools
  • AzzaMods Launcher

The .NET and Unity requirements for .NET.

Installation

Visit Beta.AzzaMods.com to download the AzzaMods Launcher and follow the installation steps.

Checking Game Compatability

Launch the AzzaMods Launcher and then launch the Unity based game you want to mod. The game should appear in the main list of games at the top of the AzzaMods Launcher. Click the game to take yourself to the landing page for the game.

The view showing the currently running games.

Enable the Mods Enabled master switch at the top left of the launcher to start modding.

The mods enabled master switch has been enabled.

The launcher will tell you if it is unable to connect / find the game. If there is an option to patch the game, then the game needs to be closed and the Patch Game button needs to be pressed. The patching process installs a full version of .NET 4 into the target game, without which modding will either be limited or not possible.

If there are no onscreen errors then the launcher is ready to use.

Enable Developer Mode

Click on the settings button at the top of the mod launcher. Navigate to the Developer tab on the left menu. Enable the Developer Mode option.

Enabling Developer Mode

Creating Your First Mod

Navigate to the SDK section of the Mod Launcher.

The mod launcher SDK page

Press CREATE MOD.

Creating a new mod in the launcher

WARNING: As per the warning, if you are creating a mod for an Xbox game or a game that is run via the Windows Store or Xbox Games Pass then the game needs to be running while creating a new mod, this is because the game files can't be read by a regular user on your machine, the mod launcher will create a shadow copy of the files required to create mods automatically for you when the game is running.

Mod Name: Enter a unique Mod Name for your Mod.

Mod Path: Type the path where you want to install the source files for your mod. The BROWSE... button allows you to use the Windows explorer to pick the path to place mods.

Press CREATE MOD -- You've just created your first mod, awesome!

A folder containing your mod will pop up when it's successful.

Editing Your First Mod

File Structure

Open the solution file. The file will be in the format of YourModName.sln and will typically have a purple Visual Studio logo on it, as you totally installed Visual Studio above like I asked you >_>

The mod files created for your mod and the solution file

That will load the Visual Studio IDE, let me show you around:

The solution explorer in visual studio

The solution explorer on the right hand side of Visual Studio allows us to browse the Mod Files for our custom mod.

Let's look at the files:

  • ExampleMod.cs
    • The file name will change based on the name of your mod that you picked earlier.
    • This contains the entry point for your mod.
  • info.json
    • This allows you to customise meta data about your mod including the name, descrption and author of the mod.

Editing info.json

Let's take a look at a sample info.json file:

{
    "modUuid": "becc97e4-a3d6-42be-999b-99c78546ab51",
    "modName": "ExampleMod",
    "binFile": "ExampleMod.dll",
    "entryPoint": "ExampleMod.ExampleMod",
    "modDescription": "",
    "modAuthor": "",
    "supportedGames": {
        "60Parsecs": true
    }
}

Explanations:

  • modUuid - This is a unique Mod UUID in the GUID format, this is used internally to control options, loading, unloading, keybinds and other state information about a mod
  • modName - This is the name of the Mod that shows up in the Mod Launcher itself, you can freely change this as often as you like.
  • binFile - This is the DLL file that contains your entry point once the mod is compiled. Don't touch this unless you know what you're doing.
  • entryPoint - This is full name of your class (including namespace) of the MonoBehaviour that will be created when the mod is loaded. Don't change this unless you changed your namespace or classname in your source files.
  • modDescription - A descrption of what your mod does. This will show up in the launcher itself
  • modAuthor - The author of the mod, throw your name / alias here.
  • supportedGames - An object that contains all the games that this mod supports. It's unlikely you can write a mod that supports multiple games, but sometimes when the code base is similar enough, it does happen. (e.g. 60 seconds and 60 seconds reatomised)

You can optionally modifiy the modName, modDescrption and modAuthor.

Editing ExampleMod.cs

Let's take a look at the ExampleMod.cs source code file. This file will be named differently depending on what you named your mod. You're looking for the one that ends in .cs.

Entire Code Block

We'll start with a copy of an entire template mod, then break it into sections to explain it to you:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using AzzaMods;
using UnityEngine;

namespace ExampleMod
{
    public class ExampleMod : MonoBehaviour
    {
        private static string optionMyOption = "My Option";
        private static string actionMyAction = "My Action";

        void OnModLoaded()
        {
            // Your mod is now loaded
            AzzaMods.Log.Info("Hello from ExampleMod");

            // Register an option
            AzzaMods.Options.RegisterBool(optionMyOption, false);
            AzzaMods.Options.RegisterAction(actionMyAction);
        }

        void OnModUnloaded()
        {
            // Undo everything, your mod is being unloaded

            // Options are automatically unregistered
            // Patches via the AzzaMods patching system are automatically unhooked
        }

        void OnOptionChanged(string optionName)
        {
            // Handle the option changing
            if(optionName == optionMyOption)
            {
                AzzaMods.Log.Info("My Option was changed to " + AzzaMods.Options.GetBool(optionName));
            }
        }

        void OnSceneChanged(string oldScene, string newScene)
        {
            AzzaMods.Log.Info("Scene was changed from " + oldScene + " to " + newScene);
        }

        // When an action happens
        void OnAction(string actionName, string actionType)
        {
            // Which action was executed?
            if (actionName == actionMyAction)
            {
                AzzaMods.Log.Info("You executed my action!");
            }
        }
    }
}

Imports

using System.Collections.Generic;
using System.Linq;
using System.Text;
using AzzaMods;
using UnityEngine;

These are the imports, these are the libraries you have access to, including the AzzaMods library which gives you access to interact with the Mod Launcher.

Namespace and Classname

namespace ExampleMod
{
    public class ExampleMod : MonoBehaviour
    {

This is Boilerplate for creating a new class, it largely won't change. This class is in the ExampleMod namespace. If you change the namespace then you will need to update info.json to match with your new namespace.

The NameSpace is what you use when importing code with the using statements above, for example, you could do using ExampleMod in a different namespace to access your code, but this probably won't be required as most likely you'll use the same namespace across your entire mod.

The classname here is ExampleMod and it inherits from MonoBehaviour which is a special type from Unity which allows us to do most things that Unity can do.

Mod Constants

private static string optionMyOption = "My Option";
private static string actionMyAction = "My Action";

These are some constants that we define to make it really simple to deal with options and actions. You can freename change the name of these variables (e.g. optionMyOption) or the value of the these variables (e.g. My Option). Changing the value will change what is displayed in the Mod Launcher.

OnModLoaded

void OnModLoaded()
{
    // Your mod is now loaded
    AzzaMods.Log.Info("Hello from ExampleMod");

    // Register an option
    AzzaMods.Options.RegisterBool(optionMyOption, false);
    AzzaMods.Options.RegisterAction(actionMyAction);
}

This chunk of code is run when the Mod is initially loaded.

AzzaMods.Log.Info("Hello from ExampleMod");

We have a line which sends a message to the AzzaMods Launcher Log Tab when the mod is initially loaded. There are several different log levels that can be used within the AzzaMods Launcher:

  • Log.Info() - Logging something informational
  • Log.Warning() - Logging a warning
  • Log.Error() - Logging an error

Each of these will have a different color and symbol in the launcher. These functions can take an infinite amount of arguments and will automatically attempt to convert what ever you provide to a string to be displayed in the launcher itself. The launcher will detect which mod called the logging functions and take note of it within the launcher UI.

AzzaMods.Options.RegisterBool(optionMyOption, false);

This line register a Bool based options called My Option which is based on the constant we defined above, with a default value of false.

AzzaMods.Options.RegisterAction(actionMyAction);

This line registers a new action (think button) that can be trigged by clicking on the button in the Mod Launcher UI, or binding a hot key.

There are a whole range of other option types and configurations that can be applied to Options, more detailed information on creating and modifiying options is available via the Options APIs.

OnModUnloaded

void OnModUnloaded()
{
    // Undo everything, your mod is being unloaded

    // Options are automatically unregistered
    // Patches via the AzzaMods patching system are automatically unhooked
}

This chunk is executed when the mod is unloaded. You should think about what a user would expect to happen when your mod is unloaded, and execute those actions here.

As stated in the comments, options are automatically unregistered and patches are automatically removed if you use the AzzaMods Patching APIs.

OnOptionChanged

void OnOptionChanged(string optionName)
{
  // Handle the option changing
  if(optionName == optionMyOption)
  {
    AzzaMods.Log.Info("My Option was changed to " + AzzaMods.Options.GetBool(optionName));
  }
}

This chunk is called when ever an option is changed, including the value or properties of that option.

We firstly check which option was changed, and then if it is the option we expected, we log the current bool based value of the option.

OnSceneChanged

void OnSceneChanged(string oldScene, string newScene)
{
    AzzaMods.Log.Info("Scene was changed from " + oldScene + " to " + newScene);
}

This API is called each time the scene is changed.

We simply send a message to the log containing the oldScene and the newScene.

OnAction

void OnAction(string actionName, string actionType)
{
    // Which action was executed?
    if (actionName == actionMyAction)
    {
        AzzaMods.Log.Info("You executed my action!");
    }
}

This API is called when the user clicks on the action we registerd (displayed as a button in the Launcher UI).

Firstly we check which action was pressed, then we log that our action was executed.

Next Steps

Take a look at our API documentation on the side and feel free to reach out via Our Discord.

Learn How To Use Reflection to access and modify other classes.

Learn How To Patch Methods to make changes to methods.

We will continue to improve the APIs over time.