Skip to content

Method patching

IPatchService registers prefix or postfix callbacks against a MethodBase. It supports static and instance methods, with or without return values. Callbacks receive the target method's arguments; instance callbacks also receive the target object, and callbacks for methods with return values can read or change the result by reference.

Choose a callback type

Target method Registration method Callback parameters
Static, returns void RegisterStaticVoidPatch object[] args
Static, returns a value RegisterStaticPatch<TResult> object[] args, ref TResult result
Instance, returns void RegisterInstanceVoidPatch<TInstance> object[] args, TInstance instance
Instance, returns a value RegisterInstancePatch<TInstance, TResult> object[] args, TInstance instance, ref TResult result

TInstance is the target method's instance type. TResult must match the target method's return type. The argument array contains the original method arguments in declaration order.

Prefix example

A prefix runs before the target method. Return true to continue to the next prefix and then the original method. Returning false stops later prefixes and skips the original method.

using System;
using System.Reflection;
using StarMap.API;
using StarMap.API.Services;

public static class ExampleTarget
{
    public static void Run(int value)
    {
        Console.WriteLine($"Running with {value}");
    }
}

[StarMapMod]
public sealed class ExampleMod
{
    private readonly IPatchService _patches;

    public ExampleMod(IPatchService patches)
    {
        _patches = patches;
    }

    [StarMapBeforeMain]
    public void Initialize()
    {
        MethodInfo target = typeof(ExampleTarget).GetMethod(
            nameof(ExampleTarget.Run),
            BindingFlags.Public | BindingFlags.Static)
            ?? throw new MissingMethodException(
                typeof(ExampleTarget).FullName,
                nameof(ExampleTarget.Run));

        _patches.RegisterStaticVoidPatch(
            IPatchService.PatchType.Prefix,
            target,
            args =>
            {
                var value = (int)args[0];
                Console.WriteLine($"Before Run({value})");
                return value >= 0;
            });
    }
}

Postfixes and return values

A postfix runs after the target method. Returning false from a postfix stops later postfix callbacks; the original method has already run. For a method that returns a value, use a result callback and modify result by reference when needed. Its generic TResult must exactly match the target method's return type.

When selecting a target with reflection, choose the intended overload explicitly. Prefer lifecycle callbacks where they meet the need; game-internal patch targets can vary across KSA versions.