Browse documentation

Ordering and priorities

Load order is not execution order. A mod loaded last can add a patch that runs first. Use these annotations to control ordering:

  • [HarmonyPriority(int)] Sets this patch's priority. Defaults to Priority.Normal (400).

  • [HarmonyBefore(string[])] Runs this patch before patches owned by any of the given Harmony IDs.

  • [HarmonyAfter(string[])] Runs this patch after patches owned by any of the given Harmony IDs.

Example:

Given the following method:

class Foo
{
    static string Bar() => "secret";
}

and Plugin 1

void Main_Plugin1()
{
    var harmony = new Harmony("net.example.plugin1");
    harmony.PatchAll(Assembly.GetExecutingAssembly());
}

[HarmonyPatch(typeof(Foo))]
[HarmonyPatch("Bar")]
class MyPatch
{
    static void Postfix(ref string __result) => __result = "new secret 1";
}

and Plugin 2

void Main_Plugin2()
{
    var harmony = new Harmony("net.example.plugin2");
    harmony.PatchAll(Assembly.GetExecutingAssembly());
}

[HarmonyPatch(typeof(Foo))]
[HarmonyPatch("Bar")]
class MyPatch
{
    static void Postfix(ref string __result) => __result = "new secret 2";
}

a call to Foo.Bar() would return "new secret 2" because both plugins register their Postfix with the same priority and so the second Postfix overrides the result of the first one. As an author of Plugin 1, you could rewrite your code to

void Main_Plugin1b()
{
    var harmony = new Harmony("net.example.plugin1");
    harmony.PatchAll(Assembly.GetExecutingAssembly());
}

[HarmonyPatch(typeof(Foo))]
[HarmonyPatch("Bar")]
class MyPatch
{
    [HarmonyAfter(["net.example.plugin2"])]
    static void Postfix(ref string __result) => __result = "new secret 1";
}

This runs after net.example.plugin2, changing the result last. Alternatively, [HarmonyPriority(Priority.Low)] puts Plugin 1 after Plugin 2's normal-priority postfix.

All priority annotations are also valid on the class. This will define the priorities for all contained patch methods at the same time.

Harmony 3 preview

For the stable release, read the 2.x documentation.