What is Patching?
Patching is the process of running code before or after a function, and sometimes even modifying it. Patching is useful to execute your code after a function, or before one if your mod breaks it entirely. Patching can even stop the original method from executing.
Setup
In your ModLoaded function we will add the following code, if you aren't patching and functions this is unnecessary.
HarmonyInstance harmonyInstance = HarmonyInstance.Create("YourName.YourMod");
harmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
This will tell harmony to use our patches that we have created., after this code has been added we can begin to write our patches. All patches have to happen either before or after a function has executed in harmony.
Prefix
Prefix happens before a function is called, let's take the example code here.
public class Bar
{
public void Foo()
{
Debug.Log("Bar")
}
}
This code will print Bar to the console, however lets say we want it to print out Foobar before hand, we can accomplish that with the following code.
[HarmonyPatch(typeof(Bar), "Foo")] // the first argument is the class type, and the second is the name of the function, note that using nameof(class.function) would also work
public class Patch_Foo // the name can be anything you want it to be, but it's better to be descriptive
{
[HarmonyPrefix] // this isn't needed if the function name is Prefix
public static bool Prefix() // if your function is named Prefix harmony will interpret it as such, if not you need the aformentioned tag. Prefix can also have a return type of void
{
Debug.Log("Foobar");
return true;
}
}
With our new patch in place Foobar is printed then Bar is printed, however if we didn't want Bar to be printed we could return false and harmony wouldn't run the patched function, only our code.
Postfix
Postfix happens after a function is called, let's take the example code from Prefix, but now we want Foobar to be printed after Foo. That'd be done with the following code.
[HarmonyPatch(typeof(Bar), "Foo")] // the first argument is the class type, and the second is the name of the function, note that using nameof(class.function) would also work
public class Patch_Foo // the name can be anything you want it to be, but it's better to be descriptive
{
[HarmonyPostfix] // this isn't needed if the function name is Postfix
public static void Postfix()
{
Debug.Log("Foobar");
}
}
This will cause Foobar to be printed after Bar is printed.
Modifying or reading a return value
Modifying the return value can be done in both Prefix and Postfix, take this code for example.
public class MyClass
{
public static int myMethod(int myInt)
{
return myInt;
}
}
If we wanted myMethod to return a different value we could do so by adding the parameter ref __result to our patch, the type of result has to match the return value of the class and must contain ref if you want to modify it, if you simply wish to read it then ref isn't necessary.
[HarmonyPatch(typeof(MyClass), "myMethod")]
public class Patch_MyClass
{
public static void Postfix(ref int __result)
{
__result = 3;
}
}
With this code, we now return 3. Keep in mind that this code works with prefix as well, however if the original function is ran then the return could be modified.
Modifying or reading parameters
Remember the code from the last section, but let's say that we want to read myInt, or modify it, that can be accomplished by adding that as a parameter to our patch.
[HarmonyPatch(typeof(MyClass), "myMethod")]
public class Patch_MyClass
{
public static void Postfix(ref int myInt) // ref is required if we want to modify it
{
myInt = 4;
Debug.Log(myInt);
}
}
Miscellaneous parameters for patching
__instance can be used in the parameters of your patch to grab the instance of the class that called the function. __state can be used to pass a variable between Prefix and Postfix between the same patched function.