Skip to main content
Version: 0.1.0

Patching the game

The WukongMP SDK is built on a custom fork of the Harmony library. While it supports most of the Hamony's API, there are some differences in how patches are discovered and enabled.

In general, refer to the official Harmony documentation when defining patches in your WukongMP mods.

Below are a few requirements that must be satisfied for patches to work correctly.

Categories are mandatory​

Each Harmony patch declared in your mod's code must be decorated with the HarmonyPatchCategory attribute, with one of the constants defined in PatchCategory, like so:

Example patch
[HarmonyPatch(typeof(BPS_PlayerTeleportSystem), "OnPlayerTeleportTo")]
[HarmonyPatchCategory(PatchCategory.Global)]
public static class PatchOnPlayerTeleportTo { ... }

As of the current version of the SDK, only patches with the PatchCategory.Global or PatchCategory.Connected category are enabled at game start.

Using TargetMethod​

Sometimes you have to use the TargetMethod method in your patch class to be able to patch a member of a private or internal class.

In the WukongMP SDK's Harmony fork this method requires the HarmonyTargetMethodHint attribute to be present. The first argument is the fully qualified class name. The second argument is the patched member name.

Example: patching an internal class
[HarmonyPatch]
[HarmonyPatchCategory(PatchCategory.Connected)]
internal static class PatchComplexSkillDoInteractAction
{
[HarmonyTargetMethodHint("b1.BUIAComplexSkill", "DoInteractAction")]
private static MethodBase TargetMethod()
{
return AccessTools.Method("b1.BUIAComplexSkill:DoInteractAction");
}
...
}

Another use case for TargetMethod are generic classes. In such cases, you must also decorate with HarmonyTargetMethodHint, providing the specialized class type and member name.

Example: Patching a generic class
[HarmonyPatch]
[HarmonyPatchCategory(PatchCategory.Global)]
public class PatchShrineRegisterFunc
{
[HarmonyTargetMethodHint(typeof(FMenuHelper<EShrineMenuTag>), "RegisterFunc")]
public static MethodBase TargetMethod()
{
var specializedType = typeof(FMenuHelper<EShrineMenuTag>);
return specializedType.GetMethod("RegisterFunc")!;
}
...
}