# 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

```csharp
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

```csharp
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](/doc/dependencies-conflicts-and-ordering-W2c7gryhWl).

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](/doc/features-geboWdIiDN) 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:

```csharp
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.