Creating a Unity Mod Manager Mod for Broforce - alexneargarder/BroforceMods GitHub Wiki
If you don't want to bother with all of these steps, you can download my ExampleMod from my repo and use it as a starting off point. Or you can use my script I created
In Visual Studio 2022, click Create a new project.

Choose the Class Library (.NET Framework) template

Name your mod whatever you want. Choose .NET Framework 3.5. If you don't see it listed, make sure you download and install it.

Now you should have your project open in Visual Studios.
Next you'll need to add the required references needed to compile the mod. To do this, first you should create a folder. It can be anywhere but I would place it in the same directory your Visual Studio Project is in.
Download the dlls in this folder on my repo and place them in that folder.
Next you'll need to right-click on References, Click Add Reference..., click Browse..., navigate to the folder you created, selected all the dlls, click Add, and then click Ok.
The code for a basic mod looks like this. You can copy and paste it into your project, but make sure you change the class name to match the name of your class file, or rename the file to match the class name. If you'd like to copy the code without all the comments, you can find the same code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HarmonyLib;
using UnityEngine;
using UnityModManagerNet;
using System.Reflection;
// The namespace is important when it comes to loading the mod
// If you change this make sure you update the EntryMethod field in the Info.json file,
// or else your mod will not load.
namespace EXAMPLE_MOD
{
// If you change the name of your class you'll need to update the Info.json file
static class Main
{
// ModEntry is mainly used to print to the log
public static UnityModManager.ModEntry mod;
// Enabled indicates whether the mod is enabled, this controls
// whether harmony patches should be modifying behavior or not
public static bool enabled;
public static Settings settings;
static bool Load(UnityModManager.ModEntry modEntry)
{
// These lines are telling Unity Mod Manager the functions it needs to call
// to display the GUI, save the Mod Settings, and Enable/Disable the mod
modEntry.OnGUI = OnGUI;
modEntry.OnSaveGUI = OnSaveGUI;
modEntry.OnToggle = OnToggle;
// This line loads the settings from the Settings.xml file
settings = Settings.Load<Settings>(modEntry);
// These lines are for executing the harmony patches
// Harmony patches are what actually change the behavior of the game
var harmony = new Harmony(modEntry.Info.Id);
var assembly = Assembly.GetExecutingAssembly();
harmony.PatchAll(assembly);
// We save a reference to modEntry for displaying messages to the log
mod = modEntry;
return true;
}
// This method handles displaying the mod settings
static void OnGUI(UnityModManager.ModEntry modEntry)
{
if (GUILayout.Button("Button 1", GUILayout.Width(100)))
{
Main.Log("Button 1 Pressed");
settings.count++;
}
GUILayout.Label("Button 1 Pressed: " + settings.count + " times");
}
static void OnSaveGUI(UnityModManager.ModEntry modEntry)
{
settings.Save(modEntry);
}
// This method is called whenever the mod is enabled / disabled
static bool OnToggle(UnityModManager.ModEntry modEntry, bool value)
{
enabled = value;
return true;
}
// This function makes printing stuff to the log easier
// Normally you would do
// Main.mod.Logger.Log("Hello World");
// With this function you can do
// Main.Log("Hello World");
// If you want to use this function in classes in other namespaces, include this line:
// using EXAMPLE_MOD;
public static void Log(String str)
{
mod.Logger.Log(str);
}
}
// If you have any mod settings that you want to have persist between game sessions you can store them here
// All you need to do is add a new variable to the Settings class below and it will automatically be saved and loaded
// The settings.xml file will automatically be updated as well
public class Settings : UnityModManager.ModSettings
{
public int count = 0;
public override void Save(UnityModManager.ModEntry modEntry)
{
Save(this, modEntry);
}
}
// Here is an example of a Harmony Patch
// Player is the class that contains the method you're patching
// GetInput is the method you're patchhing
[HarmonyPatch(typeof(Player), "GetInput")]
// Player_GetInput_Patch is simply a name for the class that contains the patch
// You can use any name here but I would recommend using a consistent naming scheme
static class Player_GetInput_Patch
{
// Prefix patches run before the method, Postfix patches run after
// Player __instance provides a reference to the current object
// that is running the method
// You can access the original arguments of the method by including
// arguments with the same name and type with the ref keyword added
public static void Prefix(Player __instance, ref bool buttonGesture)
{
// I would recommend including this in all of your patches
// If the mod is toggled off, enabled will be set to false,
// so we can simply return to avoid modifying the game behavior at all
if (!Main.enabled)
{
return;
}
if (buttonGesture)
{
// This message will display multiple times because the GetInput method is called many times per second
Main.Log("Player taunted");
}
}
}
// For more details about how Harmony Patches work, see the documentation:
// https://harmony.pardeike.net/articles/patching-prefix.html
}After you have copied that code, or written your own based off of it, you should click on Build > Build Solution to compile your project.
Next you should attempt to load your mod in-game. In order to do this you should go to your Broforce folder which will probably be here: C:\Program Files (x86)\Steam\steamapps\common\Broforce
Go to the mods folder and create a folder for your mod. If you don't see the mods folder, make sure you've installed Unity Mod Manager to Broforce and run the game at least once after installing.
Copy the dll for your compiled mod to this folder. The dll should be located in the project folder for your mod under bin > Debug.
Then create a file called Info.json. The Info.json file tells UnityModManager how to load your mod and other details about it. It should look something like this:
{
"Id": "Example Mod",
"DisplayName": "Example",
"Author": "YourName",
"Version": "1.0.0",
"AssemblyName": "ExampleMod.dll",
"EntryMethod": "EXAMPLE_MOD.Main.Load"
}The Id should match the name of the folder you created
The AssemblyName should match the name of the dll for your mod.
The EntryMethod should be "the namespace of your mod.the main class of your mod.the function which loads UnityModManager"
After you've copied the dll and created the Info.json file, you can open Broforce and see if your mod loads.
Copying the dll every time you make changes can be cumbersome, so I would recommend setting up a symbolic link between the .dll in your bin\Debug folder and the dll in your Broforce > mods folder. You can do that in the command prompt with a command like this:
mklink "C:\Program Files (x86)\Steam\steamapps\common\Broforce\mods\your mod folder\your mod.dll" "path to your project folder\bin\Debug\your mod.dll"
That way you don't have to manually copy the .dll file over every time you make a change. If you use this method you may notice that Windows likes to create these cache files though, which seem to get loaded instead of the actual linked .dll, so these will prevent your changes from showing up. To solve this I like to add a Post-build event command to my Visual Studio Projects that just deletes these caches, so every time I rebuild my project the cache files are erased, and I'm certain that I have the latest version of my mod ready to be loaded. You can find this option by right-clicking on your project in the Solution Explorer, clicking properties, and then going to Build Events. The command should look something like this: del "C:\Program Files (x86)\Steam\steamapps\common\Broforce\mods\your mod folder*.cache"