C# prefab patches

Use C# authoring for small declarative patches, generated operations, or values driven by mod configuration. It produces the same manifest model as visual authoring.

Register C# prefab patches during mod initialization, before Patch Manager closes registration.

A minimal value change

using PatchManager.CSharpPatching;
using PatchManager.PrefabPatching;
using UnityEngine.UI;

var background = PrefabPatchBuilder.ComponentAt<Image>(
    "KSP2UIWindow/Root/Window-App/Background"
);

Patching.Mod
    .PatchPrefab("toolbar-tint", "SomeWindow.prefab")
    .SetValue(
        "set-background-red",
        background,
        "m_Color.r",
        PrefabPatchValue.FromFloat(0.25)
    )
    .Register();

PatchPrefab takes a patch name and the stock Addressables key. SetValue takes a stable operation ID, a target, a serialized property path, and a value.

Inside a mod derived from the Redux mod base, you can use its mod-scoped Patch Manager property instead of Patching.Mod if that is the established pattern in your project.

Common targets

var root = PrefabPatchBuilder.GameObjectAt("Root/Panel");
var image = PrefabPatchBuilder.ComponentAt<Image>("Root/Panel/Icon");
var secondImage = PrefabPatchBuilder.ComponentAt<Image>(
    "Root/Panel",
    componentOrdinal: 1
);

Paths are slash-separated GameObject names. Component ordinal is zero-based among components of the requested type.

Common operations

The builder supports:

  • SetValue

  • SetObjectReference

  • SetActive

  • SuppressObject

  • AddObject

  • AddComponent

  • RemoveComponent

Use PrefabPatchObjectBuilder and PrefabPatchComponentBuilder to build added hierarchies. Add an object or component before later operations target it.

References

PrefabPatchBuilder.Addressable(address) points at a stock or mod Addressables key.

PrefabPatchBuilder.TargetReference(target) points at an object or component inside the effective prefab.

Coordination and caching

Use NeedsMod, NeedsPatch, ConflictsMod, BeforePatch, and related methods exactly as described in Dependencies, conflicts, and ordering.

A prefab patch applies only in campaigns where the default feature of its mod is on. Two builder methods add more conditions:

  • Feature(...): all of the listed features must also be on.

  • NoFeature(...): the patch does not apply while one or more of the listed features is on.

A bare id is a feature of your mod:

Patching.Mod
    .PatchPrefab("hard-mode-tint", "SomeWindow.prefab")
    .Feature("HardMode")
    .SetValue("set-background-red", background, "m_Color.r", PrefabPatchValue.FromFloat(0.5))
    .Register();

If generated operations depend on settings or external inputs, call Configuration(...) with stable strings representing those inputs. Changing them invalidates the resolved-plan cache. If a player must turn a change on or off per campaign, gate the change on a feature. Do not generate it from a setting.

Call Build() instead of Register() only when a tool or test needs the manifest without registering it for the session.