web stats

KATA 7 OF 8 · CODE LAYER

Code Mods with Harmony (C#)

XML and XUi can change values, content, and interface - but not behaviour that lives only in the game's compiled code. For that you write C#, compile a DLL, and use Harmony to patch game methods at runtime. This is the deepest layer, and the first one that forces EAC off.

What you'll build

A minimal code mod: a class library DLL with an IModApi entry point that applies a Harmony patch to a game method. The pattern below is the skeleton every C# 7DTD mod starts from.

Setup

  • IDE: Visual Studio 2022 or JetBrains Rider.
  • Project: a .NET Framework class library (outputs a .dll).
  • References: add the game's assemblies from 7 Days To Die/7DaysToDie_Data/Managed/ - at minimum Assembly-CSharp.dll (the game's code) and 0Harmony.dll (Harmony ships with the game), plus the UnityEngine assemblies you touch. Point the project's reference paths at that Managed folder.

You do not bundle your own Harmony - the game supplies it and loads mod assemblies natively, which is why modern code mods no longer patch Assembly-CSharp.dll on disk.

Step 1 - The IModApi entry point

The game looks for a class implementing IModApi and calls InitMod once at load. That is where you start Harmony:

using HarmonyLib;
using System.Reflection;

public class MyCodeMod : IModApi
{
    public void InitMod(Mod _modInstance)
    {
        var harmony = new Harmony("com.yourname.myfirstcodemod");
        harmony.PatchAll(Assembly.GetExecutingAssembly());
        Log.Out("[MyFirstCodeMod] loaded and patched");
    }
}

Step 2 - A Harmony patch

A patch tells Harmony "run my code before (Prefix) or after (Postfix) this game method." Postfix is the safest start - it observes or tweaks a result without replacing the original:

using HarmonyLib;

[HarmonyPatch(typeof(TargetClass), nameof(TargetClass.TargetMethod))]
public class TargetClass_TargetMethod_Patch
{
    static void Postfix(/* match the game method's parameters / return ref */)
    {
        // your behaviour change here
    }
}

The hard part of code modding is not Harmony - it is knowing which method to patch. You find that by decompiling Assembly-CSharp.dll (with dnSpy, ILSpy, or your IDE's decompiler) and reading the game's code. The patch signature (parameter names/types) must match the target method.

Step 3 - Ship it

Build the DLL and place it in the mod folder beside ModInfo.xml (the same ModInfo.xml from Kata 1). The game loads the assembly from the mod folder on startup - a code mod can also include Config/ and Resources/ alongside the DLL, since the bigger ones combine all the layers.

MyFirstCodeMod/
  ModInfo.xml
  MyFirstCodeMod.dll
  Config/        (optional XML)
  Resources/     (optional assets)

The EAC wall

This is the rule that defines the code layer: Easy Anti-Cheat blocks unsigned game assemblies, so a code mod requires EAC off - on the server and every client. Consequences:

  • Code mods are not crossplay-capable (consoles cannot disable EAC), so a code-modded server is PC-only.
  • Every player installs the DLL and launches with EAC off. This is the same line that makes total overhauls PC-only, EAC-off, all-clients-install affairs.

V3.0 change for code mods

From the V3.0 release notes: code mods now reference a single, publicized Assembly-CSharp.dll. Because the assembly is run through a publicizer, code that overrides vanilla methods may need those overrides made public. In practice most C# mods need at least a recompile against the V3.0 assemblies, and some need small visibility fixes - far less work than an XUi port, but not zero. See what V3.0 changed for modders.

Test it

  1. Build, drop the DLL next to ModInfo.xml in Mods/MyFirstCodeMod/.
  2. Launch with EAC off (the launcher option, or a dedicated server with EACEnabled=false).
  3. Check the log for your InitMod message and any Harmony patch errors (Harmony logs loudly when a target method is not found).

Common pitfalls

  • EAC still on. The DLL silently will not load. This is the first thing to check.
  • Wrong target signature. If the patched method's name or parameters do not match the game's, Harmony throws at patch time - read the log.
  • Reference paths. "Type not found" errors usually mean you did not reference the right assembly from Managed/.
  • Skipped the V3.0 recompile. A V2.6 DLL will not load on V3.0 - recompile against the publicized assembly and fix any visibility errors.

Deeper references: the community Harmony docs for 7D2D and the Harmony library itself.

Next: Kata 8 - From Modlets to a Full Overhaul. You now know all four layers. The capstone is how the big overhauls stack them - and why a game-version jump takes them months.