-
Notifications
You must be signed in to change notification settings - Fork 43
Basic usage
Geoffrey Horsington edited this page Jan 22, 2020
·
1 revision
Using Harmony usually consists of two phases:
- Define the patches and annotate them with
HarmonyPatch
attributes. - Create
Harmony
instance and callPatchAll
.
This is a quick example of the most basic patch, where Original.RollDice()
is patched to simulate the behaviour of the well-known random number generator.
using System;
using HarmonyLib;
using System.Reflection;
namespace HarmonyTest
{
class Original
{
public static int RollDice()
{
var random = new Random();
return random.Next(1, 7); // Roll dice from 1 to 6
}
}
class Main
{
static void Main(string[] args)
{
Console.WriteLine($"Random roll: {Original.RollDice()}"); // Prints: "Random roll: <some number between 1 and 6>"
// Actual patching is just a one-liner!
Harmony.CreateAndPatchAll(typeof(Main));
Console.WriteLine($"Random roll: {Original.RollDice()}"); // Will always print "Random roll: 4"
}
[HarmonyPatch(typeof(Original), "RollDice")] // Specify target method with HarmonyPatch attribute
[HarmonyPrefix] // There are different patch types. Prefix code runs before original code
static bool RollRealDice(ref int __result)
{
// https://xkcd.com/221/
__result = 4; // The special __result variable allows you to read or change the return value
return false; // Returning false in prefix patches skips running the original code
}
}
}
Refer to the next sections for a more detailed description on how to use Harmony.
- Basic usage
-
HarmonyX extensions
1.1. Patching and unpatching
1.2. Prefixes are flowthrough
1.3. Targeting multiple methods with one patch
1.4. Patching enumerators
1.5. Transpiler helpers
1.6. ILManipulators
1.7. Extended patch targets
1.8. New patch attributes -
Extending HarmonyX
2.1. Custom patcher backends -
Misc
4.1. Patch parameters - Implementation differences from Harmony