Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
We will be compiling our plugin for release, meaning that there will be no debugging options set up
First Click Build > Configuration Manager in Visual Studio
Then in the Configuration Manager window, change Active solution configuration from "Debug" to "Release", then click close
Next Click Build > Build Solution
If you used the earlier project settings your plugin should now be created inside your r2modman profile
You should now be able to launch your modded game and see in the BepInEx log our logged message
The following Plugin class will allow BepInEx to load and handle your compiled assembly as a plugin
In Visual studio right click "Class1.cs" in the solution explorer and rename it to "Plugin.cs". Choose "Yes" to rename all references
If you do not have a Class1.cs you can create Plugin.cs instead by choosing Project > Add Class...
Copy and paste the following code into "Plugin.cs" replacing the entire contents of the file
If you do not see where to paste the code into, double click the Plugin.cs file in the solution explorer
Save your changes by selecting File > Save Plugin.cs
You should now be ready to compile your first plugin
We create a new class that inherits from the BepInEx BasePlugin class. We give this new class a special attribute (the BepInPlugin
thing above the class) which BepInEx uses to make this class into a full-fledged plugin. The arguments we supply to the attribute include:
The GUID: "NewbiePluginAuthor.MyFirstPlugin"
This is an identifier which should uniquely identify the plugin. Typically just author.pluginname
should suffice.
The plugin name: "MyFirstPlugin"
The plugin version: "1.0.0"
This uses semantic versioning.
Visual Studio Community allows you to navigate, edit and compile code.
Download Visual Studio here by click "Free Download" underneath the Community section
Run "VisualStudioSetup.exe" from your download folder
Continue through the process until you get to the "Installing" window with the "Workloads" tab
Under the "Desktop & Mobile" section select ".NET desktop development"
Under the "Gaming" section select "Game development with Unity"
Once you have your preferred components selected click "Install" on the bottom right
Wait for the heat death of the universe until your IDE is installed
Continue through the rest of the set up until a "Get started" window appears
Signing in to Visual Studio is optional
You should now be ready to create your C# class library project
The following Patch class will use HarmonyX to allow us to modify how GTFO behaves
First, in Visual Studio, click Project > Add Class and change Class1.cs to Patch.cs
Next replace the pre-generated code with the following
After that go back to our Plugin class and add the following line to your Load method
You can now compile the plugin and when you click the About Rundown button in-game you will unlock a new rundown
The line we added to our load method means that when the plugin loads it will create a Harmony instance and apply all the patches it can find (note we supply Harmony with the same GUID we saw earlier). The [HarmonyPatch]
attribute we gave our Patch class helps Harmony find it (though it isn't always required depending on how you go about patching).
When Harmony finds our Patch class it'll then look for any patching methods. The attributes we gave to the MyPatch method label it as such a patching method. The [HarmonyPostfix]
attribute tells Harmony a little about how we want to do our patch while the [HarmonyPatch(...)]
attribute tells Harmony what we want to patch. In this case it specifies that we want to patch the Setup method in the CM_PageRundown_New class. Our patch replaces the action of the about rundown button with our own code.
If multiple patch classes are desired first create a harmony instance and then use the types
To find more information on how to use HarmonyX please reference their Github Wiki
How to set up your project for editing and compiling
We will be creating a Library project written in C# targeting all platforms
First create a new project and choose "Class Library" - "A project for creating a classlibrary that targets .NET or .NET Standard"
Then write a name into the Project name field, such as "MyFirstPlugin" and click "Next"
Next ensure you have ".NET 6.0 (Long-term support)" selected as your Framework and click "Create"
When the project is finished creating you should see "Class1.cs" open
Click Project > Edit Project File and replace it with the following
The following project settings assume you have r2modman installed in the Default location with BepInEx installed and run at least once
You can change which r2modman profile is used by editing the Profile property Additionally, you can also change the BepInEx path to your preferred location by editing the BepInEx property
Finally save the changes to the csproj file
You should now be ready to create your Plugin class
This guide goes over setting up a development environment using Visual Studio and compiling your first plugin
A Plugin is a compiled C# assembly file that is loaded by BepInEx to allow for custom code to be executed, such as patches or custom behaviour
This guide assumes you are running windows 10 or 11, own GTFO on steam, and have r2modman installed
Is this missing something you want help with? Try asking in our Discord server.
This is a very basic summary of patching. See the harmony documentation for more details.
Typically, when making a plugin, developers will want to change how something in the base game behaves. Of course, in order to change the normal behavior we need to know what piece(s) of code in the base game determine that behavior so that we can target them with a patch. This means that part of the challenge of making a plugin is determining which method(s) to patch in the first place! If you're unsure how to go about determining which methods to target consider asking in our Discord Server.
The two basic kinds of patches are Prefix and Postfix patches. Both of these target some original method in the game's code in the same way through the [HarmonyPatch(...)]
attribute (though there are also more complicated ways to determine which method they target).
Postfix patches use the [HarmonyPostFix]
attribute. Postfix patches run after the original method. As with any patch this allows you to run any code you want at this point, but also importantly, this can let you alter the normal return value of that method.
Prefix patches use the [HarmonyPreFix]
attribute. Prefix patches run before the original method. They can alter the arguments of the original method before that method runs. They can also control whether or not to skip the original method completely.
Unfortunately, a more complicated kind of patch (Transpiler patches) which offers some unique benefits doesn't quite work with how GTFO is compiled.