Harmony
A library for patching, replacing and decorating .NET and Mono methods during runtime
Top Related Projects
Cecil is a library to inspect, modify and create .NET programs and libraries.
Unity / XNA game patcher and plugin framework
The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono
.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
- 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.
- 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.
- 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
-
Install Harmony via NuGet:
Install-Package Lib.Harmony
-
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(); } }
-
Define your patches using attributes as shown in the code examples above.
-
Call the
Initialize
method when your mod loads to apply the patches.
Competitor Comparisons
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));
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.
.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 designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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.
Top Related Projects
Cecil is a library to inspect, modify and create .NET programs and libraries.
Unity / XNA game patcher and plugin framework
The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot