Skip to content

Basic usage

Geoffrey Horsington edited this page Jan 22, 2020 · 1 revision

Using Harmony usually consists of two phases:

  1. Define the patches and annotate them with HarmonyPatch attributes.
  2. Create Harmony instance and call PatchAll.

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.