The SE Launcher uses the Harmony 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
Below is an example plugin patch that adds a simple message to the game log each time the world is autosaved.
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!");
}
}
MySession.SaveEnded
, which is called by the game when an autosave completes.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.To apply the patch, you must initialize Harmony in your plugin’s Init()
method:
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.
"TestPlugin"
in this case) should be unique per plugin to avoid conflicts.Patch()
and Unpatch()
methods instead of PatchAll()
.For more complex patching scenarios, refer to the Harmony documentation:
https://harmony.pardeike.net/articles/intro.html