AgentSkillsCN

harmony

为 BepInEx 插件中的方法拦截与运行时修改创建 Harmony 补丁。 适用场景:拦截 EFT 游戏方法、修改机器人行为、钩取游戏生命周期事件,或对第三方模组方法进行补丁修复。

SKILL.md
--- frontmatter
name: harmony
description: |
  Creates Harmony patches for method interception and runtime modification in BepInEx plugins.
  Use when: intercepting EFT game methods, modifying bot behavior, hooking into game lifecycle events, or patching third-party mod methods.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash

Harmony Skill

Harmony is the runtime patching library used by BepInEx to intercept and modify game methods without touching original assemblies. In BotMind, Harmony patches are used to hook into EFT's game lifecycle (raid start/end), bot spawning events, and player interactions. All patches live in src/client/Patches/ and are auto-applied via Harmony.PatchAll() in BotMindPlugin.cs.

Quick Start

Prefix Patch (Run Before Original)

csharp
[HarmonyPatch(typeof(GameWorld), nameof(GameWorld.OnGameStarted))]
internal static class GameStartedPatch
{
    [HarmonyPrefix]
    private static void Prefix()
    {
        try
        {
            MedicBuddyController.Instance?.OnRaidStarted();
            BotMindPlugin.Log?.LogInfo("Raid started - modules initialized");
        }
        catch (Exception ex)
        {
            BotMindPlugin.Log?.LogError($"GameStartedPatch error: {ex.Message}");
        }
    }
}

Postfix Patch (Run After Original)

csharp
[HarmonyPatch(typeof(GameWorld), "Dispose")]
internal static class GameWorldDisposePatch
{
    [HarmonyPostfix]
    private static void Postfix()
    {
        MedicBuddyController.Instance?.OnRaidEnded();
        LootFinder.ClearCache();
    }
}

Key Concepts

ConceptUsageExample
[HarmonyPatch]Declares target method[HarmonyPatch(typeof(BotOwner), "Update")]
[HarmonyPrefix]Runs before original, can skipReturn false to skip original
[HarmonyPostfix]Runs after originalAccess __result to modify return
[HarmonyTranspiler]IL-level modificationInject/remove instructions
__instanceReference to patched objectBotOwner __instance
__resultReturn value (postfix only)ref bool __result

Common Patterns

Conditional Execution with Prefix

When: Skip original method based on custom logic

csharp
[HarmonyPrefix]
private static bool Prefix(BotOwner __instance)
{
    // Skip original if MedicBuddy bot
    if (MedicBuddyController.IsMedicBuddyBot(__instance))
        return false; // Don't run original
    
    return true; // Run original
}

Modifying Return Values

When: Change what a method returns without rewriting it

csharp
[HarmonyPostfix]
private static void Postfix(ref bool __result, BotOwner __instance)
{
    // Force bots to always consider looting safe
    if (BotMindConfig.ForceEnableLooting.Value)
        __result = true;
}

Accessing Private Fields

When: Read/write private state from patched class

csharp
[HarmonyPostfix]
private static void Postfix(BotOwner __instance)
{
    var privateField = Traverse.Create(__instance)
        .Field("_internalState")
        .GetValue<BotState>();
}

See Also

  • patterns - Patch types, parameter injection, error handling
  • workflows - Creating patches, debugging, testing

Related Skills

  • See the bepinex skill for plugin lifecycle and when patches are applied
  • See the csharp skill for reflection patterns used with Traverse
  • See the unity skill for MonoBehaviour lifecycle hooks that complement patches