Convert Figma logo to code with AI

pardeike logoHarmony

A library for patching, replacing and decorating .NET and Mono methods during runtime

5,147
485
5,147
11

Top Related Projects

2,710

Cecil is a library to inspect, modify and create .NET programs and libraries.

4,714

Unity / XNA game patcher and plugin framework

The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono

14,915

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.

Quick Overview

Harmony is a library for patching, replacing, and decorating .NET and Mono methods during runtime. It's designed to modify compiled code without changing the original source, making it particularly useful for modding games and applications. Harmony is widely used in the modding community for games like RimWorld and Cities: Skylines.

Pros

  • Allows for non-destructive patching of methods, preserving the original code
  • Supports a wide range of patching techniques, including prefix, postfix, and transpiler patches
  • Provides a high-level API that simplifies the process of method manipulation
  • Works with both .NET Framework and .NET Core applications

Cons

  • Can be complex to use for beginners unfamiliar with reflection and IL code
  • Potential for conflicts when multiple mods patch the same methods
  • Performance overhead, especially when using transpilers
  • Requires careful management to avoid introducing bugs or instabilities

Code Examples

  1. Basic Prefix Patch:
[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
class Patch
{
    static bool Prefix()
    {
        Console.WriteLine("Prefix patch executed");
        return true; // Continue to original method
    }
}

This example adds a prefix patch to TargetMethod in TargetClass, printing a message before the original method executes.

  1. Postfix Patch with Result Modification:
[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
class Patch
{
    static void Postfix(ref int __result)
    {
        __result *= 2; // Double the result of the original method
    }
}

This postfix patch doubles the integer result of the target method.

  1. Transpiler Patch:
[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
class Patch
{
    static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
    {
        foreach (var instruction in instructions)
        {
            if (instruction.opcode == OpCodes.Ldc_I4_1)
            {
                yield return new CodeInstruction(OpCodes.Ldc_I4_2); // Replace 1 with 2
            }
            else
            {
                yield return instruction;
            }
        }
    }
}

This transpiler patch replaces all occurrences of the integer 1 with 2 in the IL code of the target method.

Getting Started

  1. Install Harmony via NuGet:

    Install-Package Lib.Harmony
    
  2. Create a Harmony instance and apply patches:

    using HarmonyLib;
    
    public class MyMod
    {
        public static void Initialize()
        {
            var harmony = new Harmony("com.example.patch");
            harmony.PatchAll();
        }
    }
    
  3. Define your patches using attributes as shown in the code examples above.

  4. Call the Initialize method when your mod loads to apply the patches.

Competitor Comparisons

2,710

Cecil is a library to inspect, modify and create .NET programs and libraries.

Pros of Cecil

  • Lower-level IL manipulation, offering more fine-grained control
  • Broader scope, allowing for more extensive code modification and analysis
  • More mature project with a longer history and wider adoption

Cons of Cecil

  • Steeper learning curve due to its lower-level nature
  • Requires more code to achieve simple runtime patching tasks
  • Less focused on runtime patching, making some common modding tasks more complex

Code Comparison

Cecil (modifying a method):

var assembly = AssemblyDefinition.ReadAssembly("MyAssembly.dll");
var method = assembly.MainModule.GetType("MyNamespace.MyClass").Methods.First(m => m.Name == "MyMethod");
var il = method.Body.GetILProcessor();
il.InsertBefore(method.Body.Instructions[0], il.Create(OpCodes.Ldstr, "Hello, World!"));
il.InsertBefore(method.Body.Instructions[0], il.Create(OpCodes.Call, method.Module.ImportReference(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))));

Harmony (patching a method):

var harmony = new Harmony("com.example.patch");
var original = typeof(MyClass).GetMethod("MyMethod");
var prefix = typeof(MyPatch).GetMethod("Prefix");
harmony.Patch(original, new HarmonyMethod(prefix));
4,714

Unity / XNA game patcher and plugin framework

Pros of BepInEx

  • Provides a complete modding framework, including plugin loading and configuration management
  • Supports multiple Unity game engines and non-Unity games
  • Offers a user-friendly GUI for configuring mods and plugins

Cons of BepInEx

  • Steeper learning curve for beginners due to its comprehensive nature
  • May have a larger performance overhead compared to Harmony alone
  • Requires more setup and configuration for simple patching tasks

Code Comparison

BepInEx (plugin example):

[BepInPlugin("com.example.plugin", "Example Plugin", "1.0.0")]
public class ExamplePlugin : BaseUnityPlugin
{
    void Awake()
    {
        // Plugin startup logic
        Logger.LogInfo("Plugin is loaded!");
    }
}

Harmony (patch example):

[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
class Patch
{
    static void Postfix(ref int __result)
    {
        __result *= 2;
    }
}

BepInEx is a comprehensive modding framework that includes plugin management and configuration tools, while Harmony focuses specifically on runtime method patching. BepInEx offers more features but may be overkill for simple patching needs, whereas Harmony is more lightweight and focused on method manipulation.

The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono

Pros of MelonLoader

  • Provides a complete modding framework, including mod loading and management
  • Supports a wider range of Unity games, including IL2CPP-based games
  • Offers built-in console and logging features for easier debugging

Cons of MelonLoader

  • Larger and more complex, potentially harder to integrate for simple patching needs
  • May have a steeper learning curve for developers new to modding
  • Could introduce more overhead due to its comprehensive feature set

Code Comparison

MelonLoader:

[HarmonyPatch(typeof(ExampleClass), "ExampleMethod")]
public class ExamplePatch
{
    public static void Postfix(ref int __result)
    {
        __result *= 2;
    }
}

Harmony:

var harmony = new Harmony("com.example.patch");
var original = typeof(ExampleClass).GetMethod("ExampleMethod");
var postfix = typeof(ExamplePatch).GetMethod("Postfix");
harmony.Patch(original, postfix: new HarmonyMethod(postfix));

Both libraries use similar patching concepts, but MelonLoader provides attribute-based patching, while Harmony offers more programmatic control. MelonLoader is better suited for comprehensive modding projects, while Harmony excels in targeted patching scenarios.

14,915

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.

Pros of runtime

  • Comprehensive .NET runtime implementation with extensive features and optimizations
  • Official Microsoft project with robust community support and regular updates
  • Covers a wide range of .NET functionalities, including core libraries and runtime components

Cons of runtime

  • Large and complex codebase, potentially challenging for newcomers to navigate
  • Primarily focused on core .NET functionality, not specifically designed for modding or patching

Code Comparison

runtime:

public static unsafe int Main(string[] args)
{
    int exitCode = 0;
    try
    {
        exitCode = ProgramMain(args);
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
        exitCode = 1;
    }
    return exitCode;
}

Harmony:

public static void PatchAll()
{
    var harmony = new Harmony("com.example.patch");
    harmony.PatchAll();
}

Summary

Runtime is a comprehensive .NET runtime implementation, offering a wide range of features and optimizations. It's an official Microsoft project with strong community support. However, its large codebase can be challenging to navigate, and it's not specifically designed for modding.

Harmony, on the other hand, is a specialized library for runtime patching, making it more suitable for modding scenarios. It offers a simpler API for patching methods but has a narrower focus compared to the broader functionality of runtime.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Harmony
Version 2.3
A library for patching, replacing and decorating
.NET and Mono methods during runtime.

About

Harmony gives you an elegant and high level way to alter the functionality in applications written in C#. It works great in games and is well established in titles like

• Rust
• Rimworld
• 7 Days To Die
• Stardew Valley
• Subnautica
• Oxygen Not Included
• Besiege
• Cities:Skylines
• Kerbal Space Program
• Resonite
• BattleTech
• Slime Rancher

and others like Ravenfield, Sheltered, Staxel, The Ultimate Nerd Game, Total Miner, Unturned, SCP: Secret Laboratory ...

It is also used in unit testing WPF controls at Microsoft and Google and in many other areas.

How it works

If you develop in C# and your code is loaded as a module/plugin into a host application, you can use Harmony to alter the functionality of all the available assemblies of that application. Where other patch libraries simply allow you to replace the original method, Harmony goes one step further and gives you:

• A way to keep the original method intact
• Execute your code before and/or after the original method
• Modify the original with IL code processors
• Multiple Harmony patches co-exist and don't conflict with each other
• Works at runtime and does not touch any files

Installation

If you want a single file, dependency-merged assembly, you should use the Lib.Harmony nuget package. This is the preferred way.

If you instead want to supply the dependencies yourself, you should use the Lib.Harmony.Thin nuget package. You get more control but you are responsible to make all references available at runtime.

Documentation

Please check out the documentation and join the official discord server.

Contribute

I put thousands of hours into this project and its support. So every little action helps:

• Become a GitHub sponsor or a Patreon
• Upvote this stackoverflow answer
• Spread the word in your developer communities

This project uses the great MonoMod.Core library by 0x0ade and nike4613.

Harmony 1

Harmony 1 is deprecated and not under active development anymore. The latest version of it (v1.2.0.1) is stable and contains only minor bugs. Keep using it if you are in an environment that exclusively uses Harmony 1. Currently Harmony 1.x and 2.x are NOT COMPATIBLE with each other and SHOULD NOT BE MIXED. The old documentation can still be found at the Wiki.