79 lines
2.6 KiB
Markdown
79 lines
2.6 KiB
Markdown
---
|
||
title: Patching
|
||
description: This article explains how to use versatile Harmony library in launcher environment
|
||
published: true
|
||
date: 2025-07-07T15:32:19.754Z
|
||
tags:
|
||
editor: markdown
|
||
dateCreated: 2025-07-07T15:32:17.950Z
|
||
---
|
||
|
||
# Patching Game Code
|
||
|
||
The SE Launcher uses the **[Harmony](https://harmony.pardeike.net)** library to patch and extend the behavior of the game at runtime. Plugins are also encouraged to use Harmony, as it allows for **safe and compatible method patching** even when multiple plugins modify the same methods.
|
||
|
||
Harmony is widely used in the modding ecosystem and offers powerful features for injecting code before, after, or instead of existing method logic.
|
||
|
||
> This article does not cover the full scope of Harmony’s capabilities. Developers should refer to the official documentation for detailed information:
|
||
> [https://harmony.pardeike.net/articles/intro.html](https://harmony.pardeike.net/articles/intro.html)
|
||
|
||
---
|
||
|
||
## Simple Hello World Patch
|
||
|
||
Below is an example plugin patch that adds a simple message to the game log each time the world is autosaved.
|
||
|
||
### Patch Class
|
||
|
||
```csharp
|
||
using HarmonyLib;
|
||
using NLog;
|
||
using Sandbox.Game.World;
|
||
|
||
namespace TestPlugin;
|
||
|
||
[HarmonyPatch(typeof(MySession), nameof(MySession.SaveEnded))]
|
||
public static class SavePatch
|
||
{
|
||
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||
|
||
public static void Prefix()
|
||
{
|
||
Log.Info("Hello world!");
|
||
}
|
||
}
|
||
````
|
||
|
||
### What it does:
|
||
|
||
* The patch targets `MySession.SaveEnded`, which is called by the game when an autosave completes.
|
||
* A `Prefix()` method is defined, which means it will run **before** the original method.
|
||
* `Log.Info("Hello world!")` will be printed to the log each time the game autosaves.
|
||
|
||
---
|
||
|
||
## Applying the Patch in Your Plugin
|
||
|
||
To apply the patch, you must initialize Harmony in your plugin’s `Init()` method:
|
||
|
||
```csharp
|
||
using HarmonyLib;
|
||
|
||
public void Init(object gameInstance)
|
||
{
|
||
new Harmony("TestPlugin").PatchAll(typeof(Plugin).Assembly);
|
||
}
|
||
```
|
||
|
||
This line scans your plugin assembly for `[HarmonyPatch]` attributes and applies all defined patches.
|
||
|
||
---
|
||
|
||
## Notes
|
||
|
||
* The Harmony ID (`"TestPlugin"` in this case) should be unique per plugin to avoid conflicts.
|
||
* Harmony patches are designed to **coexist across multiple plugins**, so long as they do not directly conflict by trying to replace the same method behavior entirely.
|
||
* If needed, you can control patching more granularly with `Patch()` and `Unpatch()` methods instead of `PatchAll()`.
|
||
|
||
For more complex patching scenarios, refer to the Harmony documentation:
|
||
[https://harmony.pardeike.net/articles/intro.html](https://harmony.pardeike.net/articles/intro.html) |