Tutorial Coding Changing the Return Value of a Method with Harmony

Users who are viewing this thread

Tutorials for how to work with Harmony can be a bit hard to come by and sometimes difficult to understand, especially if you're new to this kind of modding. So just thought I'd post a simple tutorial of how to change the return value of a native method.

In this case, we'll be adding a button to the Escape Menu whilst at the campaign map. This tutorial assumes you already have Visual Studio and some experience using it.

Getting Started
First of all we'll have to find the code we want to patch, now there are different ways you can go about doing this but this is my procedure:

Copy all the relevant DLL files into a separate folder on for example your desktop. Relevant DLL files are those found inside the modules Native, SandBox, StoryMode and CustomBattle. As well as all the ones inside the main bin folder that starts with TaleWorlds.*. For example TaleWorlds.Core.dll.

Use a program such as JetBrains DotPeek or dnSpy to decompile and read the contents of these DLL files. Do note that this is dirty, decompiled code and not necessarily what the original code looks like. But it's more than clean enough for us to make use of. Personally I am used to and prefer DotPeek. So for the sake of this tutorial, this is what I will be using.

Using DotPeek
When you have all the DLLs nicely available in the one same folder, you can add them all to DotPeek - either via the toolbar or simply dragging and dropping them. Once this is done, we can now go ahead and try and find some of the relevant code!

If you press CTRL+T you can search for some text "everywhere". This means it'll iterate through each and every class in each and every DLL you added. It sounds like a slow procedure but DotPeek actually does this really quickly.

Since we'll be editing the escape menu, we already have some things we can search for such as the button texts. For example "Return To The Game", "Campaign Options", "Options", "Save", "Save As" and etc. It is not case-sensitive.

Searching for "return to the game" should give us a few results, with the one most likely to be what we need inside the MapScreen class. We'll also find that this text is inside a method called GetEscapeMenuItems() - a quick glance at the code and it's fairly easy to confirm that this is what we want to modify. In fact now we actually already have all the information we need to modify this!

As we can see, it's a simple method which returns a list of EscapeMenuItemVM objects, which contains the text displayed on the button as well as code that controls its behavior such as whether it's enabled by default and what happens when you click it.

The Code
As I mentioned earlier, this tutorial assumes you have some prior knowledge with Visual Studio - so you should know how to add HarmonyLib to your project via NuGet or other means as well as working with the IDE to add the relevant references.

First of all we need to create a new instance of Harmony, I do this in my SubModule class like this;
YDe5Jc9.png

Next up, I'll be creating a new folder called "Patches" and a new class inside called MapScreenPatch. You may call these whatever you want, but I suggest sticking to a similar style to keep your code readable.

In here my code looks like this;
3lrhBeL.png

Okay so now to how it all works. In our Postfix method we need to indicate what kind of type it's going to return. Since the original method returns a list of a certain type - we need to do the same. This part I have highlighted in red.

Next up, we need to fetch the value returned by the original method. To do this, we need to use a special parameter name - "__result", again with a matching type. This is highlighted in green.

Next, we can go ahead and make our own list of buttons, in this case I only made one but you could add pretty much as many as you'd like. Do note however that unfortunately the background image of the escape menu does not automagically resize to fit its contents. This part is highlighted in blue.

Next, we need we can merge the original list of buttons with ours and return the new list. This part is highlighted in yellow. Since we just add our buttons into the original list they will be at the bottom of the menu. You can change this behavior by adding it at a certain index.

And there you go, your new button now shows up in the escape menu and prints a message when clicked!
89j9ihB.png

Credits/Sauce
Credits go to pardeike, the author of HarmonyLib as well as his wiki pages found here. If you intend to use Harmony I highly suggest you bookmark that page.

Hopefully this will prove useful to some of you!
 
Back
Top Bottom