Streets of Rogue Guide

How to make mods with BepInEx for Streets of Rogue

How to make mods with BepInEx

Overview

Here you will learn how to make Streets of Rogue mods using BepInEx.I assume you have basic knowledge of C#, so I’m not going to explain how classes and attributes work.

0. Foreword

I’m not a professional programmer and English is not my native language, so there might be some errors and mistakes.

1. Let’s install BepInEx

Download the latest version of BepInEx here:
Move contents of the archive to directory:
/Steam/SteamApps/common/Streets of Rogue/
Now run the game once, and that’s it. BepInEx is installed.

2. Creating a new project

In this guide we will be using Microsoft Visual Studio to make mods.
So, if you don’t have Visual Studio installed, install it.

Open Visual Studio and create a new project:
Select template “C# Class Library (.NET Framework)”:
Now select your project name, where it will be stored and solution name. And for Framework select .NET Framework 3.5 4.5.2. Then click “Create”.
Great! You made a project for your mod!

3. Gathering dependencies

Go to your solution directory and create a new folder, let’s call it “Libraries”:
Now go to /Steam/SteamApps/common/Streets of Rogue/ and copy these .dll files to our new folder:
/BepInEx/core/BepInEx.dll
/BepInEx/core/0Harmony.dll
/StreetsOfRogue_Data/Managed/UnityEngine.dll
/StreetsOfRogue_Data/Managed/UnityEngine.CoreModule.dll
/StreetsOfRogue_Data/Managed/Assembly-CSharp.dll
…and any other .dlls that you might need.
In the end you should have something like this:
Now go to Visual Studio. In the upper right corner you should find Solution Explorer. Find your project, right-click on References and select “Add reference…”:
At the bottom of a new window click “Browse…”:
Go to your “Libraries” folder and select all .dll files in there:
Click “Add” and then “OK”.
Now you will be able to reference these .dlls in your mod!

4. Basics of modding

Let’s add usings that we will need:
Create a new class and edit it to inherit from BaseUnityPlugin:
Then add 3 const strings, called “pluginGuid”, “pluginName” and “pluginVersion” and fill them accordingly:
“pluginGuid” – is a Globally Unique ID, that your mod will have.
“pluginName” – is your mod’s name, that will be displayed in console.
“pluginVersion” – is your mod’s version. It must be in format 1.2[.3[.4]], that can be parsed by System.Version.
Now add a BepInPlugin attribute to your class and use const strings that we just made as arguments (GUID, Name, then Version):
Let’s write a Hello world code in our plugin:
Awake() method is called once both the game and the plugin are loaded. You can also use Start(), but it is not recommended.

5. Testing and Debugging

After making a mod, you can build it by pressing “Build <Your mod name>” or “Build solution” in “Build” category:
Then go to this directory in your solution folder /<Your mod name>/bin/Debug. There you will find your mod:
To install the mod, put it in <Game root folder>/BepInEx/plugins:
Also, you can enable BepInEx console by going in <Game root folder>/BepInEx/config and editing a line in BepInEx.cfg:
Then just run the game and the console will appear:
BepInEx logs are stored in <Game root folder>/BepInEx/LogOutput.log:

6. Harmony (Prefix Patches)

If you want to somehow alter in-game code, then you can use either preloader patching or Harmony patching. I have no idea how preloader patching works, so I will explain how to use Harmony in this guide.

First of all, let’s find the method that we want to alter in Assembly-CSharp.dll. You can use dnSpy or any other assembly viewer.
For example, let’s make this method work for our colors:
For that, we need to create a prefix patch. It means that our method will execute right before the original. Let’s make that method:
Make sure that this method is static and has exactly the same argument names and types!
Let’s make it so that if a color name starts with “:” (semicolon), then it is considered “custom”:
Now this method will execute, and then the original method will be executed. But what if we do not want the original to execute? Because in this case the original will overwrite our custom colors!
Just make your method return bool value:
If your prefix-method returns true, the original method will be executed. If false – then the original won’t be executed.
By the way, you can remove arguments that you don’t need:
After we made a patch method, we need to patch it into the game.
For that we need to initialize a new instance of Harmony (use your mod’s GUID for Id), then find both original and patch methods, and finally patch the original:
RogueLibs users can use this extension method instead:
Or the RoguePatcher class:

7. Harmony (Postfix Patches and Underscores)

We covered how prefix-methods work. But you can also create postfix-methods! They will execute right after the original.
Let’s find another method that we want to patch:
In here we want to add our own elements to this.listUnlocks. Let’s make a method:
And… we’ve encountered a problem. How do we reference the caller object?
Easy! Just add an argument named “__instance” (two underscores) and use it instead of “this” keyword:
But… we can use only public elements. To get private fields’ values we can either get the value using AccessTools (too long):
Or just add another argument called “___<Field name>” (three underscores):
Also, if you want to change the field’s value, use “ref” keyword:
You need “ref” only if you’re replacing an object with a different one (or changing a struct).

In postfix-methods you can also reference the result value using “__result” (two underscores) argument. To change it, use “ref” keyword:
There is also another method of making postfix patches – passing the result through your postfix-method:
And don’t forget to patch your postfixes!:

8. Harmony (Auto-Patching, Arguments)

You can do auto-patching using attributes. But you won’t have much control over how this patching goes. So, I recommend using manual patching.
If you have multiple methods with the same name, like here:
Then you need to specify what arguments your method has:

9. Modding Libraries, RogueLibs

You can use modding libraries, for example – RogueLibs.
You can import modding libraries the same way as you did with other .dll files – by dragging them in your “Libraries” folder, and adding them in project’s References:

Also don’t forget to install RogueLibs as a mod. Put it in BepInEx/plugins folder:
You can find information about RogueLibs here:
And download here:

Just don’t forget to put a BepInDependency attribute if you’re going to use RogueLibs:

Some Examples

Ammo and Durability Mutators source code:
You can download this mod in the #modding-gallery in Streets of Rogue Discord: [link]

Rocket Bullets Mutators source code:

10. Conclusion

You can find more guides on Harmony here:
There is a lot more features than I covered in this guide.

If you need further help, just ask someone on official Streets of Rogue Discord server (channel #modding):

Addendum Guide

[link]
SteamSolo.com