# Patching from C#

Everything you can do in a Lua patch you can also do from a C# mod. PatchManager exposes a C# patching API that mirrors the Lua surface: the same passes, buckets, gates, dependencies, and the same `"remove"` behavior, expressed as C#. Use it when your mod is already a compiled assembly and you would rather keep your patches in C# alongside the rest of your code, with full type safety on the asset wrappers.

The same value wrappers you use in Lua (`PartUserData`, `CelestialBodyUserData`, and so on) are the types you get in C#, with the same helpers.

## One difference from Lua: field access

In a Lua patch you read and write an asset's JSON fields as dynamic members: `part.crashTolerance`. That dynamic member access is a Lua feature and does not exist in C#. In C# you reach the same fields through a string indexer instead:

```csharp
part["crashTolerance"] = 30.0;          // not part.crashTolerance
double m = part["mass"];                 // implicit conversion to double
bool heavy = part["mass"] > 5.0;
```

The indexer returns a wrapper that converts implicitly to `double`, `float`, `int`, `long`, `bool`, and `string`, and accepts those types on assignment, so writing a number or reading one just works. The typed helper methods (`AddModule`, `engineModes`, and the rest) are real C# methods and members, so those you call normally. It is only the raw JSON fields that move from `.field` in Lua to `["field"]` in C#.

## The fluent style

Most C# mods derive from `KerbalMod`, which gives you a `PM` property: a patch scope already bound to your mod's id. A domain method on it starts a patch you chain on, the C# equivalent of `PM.Parts:Patch(...)` in Lua. Register your patches from `OnPreInitialized`:

```csharp
using Redux.ExtraModTypes;

public class MyMod : KerbalMod
{
    public override void OnPreInitialized()
    {
        PM.PatchPart("KerbalImpactToleranceFix")
            .Named("eva_kerbal")
            .Do(part => part["crashTolerance"] = 30.0);
    }
}
```


:::warning
**Register from** `**OnPreInitialized**`**, not later.** By the time `OnInitialized` runs, PatchManager has already flushed its queue and run the patch flow, so a patch registered after that throws. This is the same rule as Lua, where registration happens once, up front.

:::

If your patch code is not inside a `KerbalMod` (a static helper, a Harmony patch, some other entry point), get a scope from `Patching` instead: `Patching.Mod` binds to the calling assembly's mod id, and `Patching.ForMod("YourModId")` names it explicitly. `KerbalMod`'s `PM` is just `Patching.ForMod` with your id filled in, so the chain after it is identical either way.

The domain methods mirror the Lua submodules:

| C#  | Lua equivalent |
|-----|----------------|
| `.PatchPart(name)` | `PM.Parts:Patch` |
| `.PatchPlanet(name)` | `PM.Planets:Patch` |
| `.PatchDefaultGalaxy(name)` | `PM.Planets:PatchDefaultGalaxy` |
| `.PatchAtmosphereOverride(name)` / `.PatchCloudOverride(name)` | the planets override methods |
| `.PatchResource(name)` | `PM.Resources:Patch` |
| `.PatchExperiment(name)` / `.PatchScienceRegion(name)` / `.PatchTechNode(name)` / `.PatchDiscoverables(name)` | the science methods |
| `.PatchMission(name)` | `PM.Missions:Patch` |
| `.PatchJson(label, name)` | `PM.JSON:Patch` |

## The fluent chain

`PatchBuilder<T>` carries the same methods as the Lua chain, typed to the asset wrapper `T`:

* `.Early()`, `.Late()`, `.First()`, `.Last()` for pass and bucket.
* `.Named(...)`, `.NotNamed(...)` for targeting.
* `.Needs(...)`, `.Conflicts(...)`, `.NeedsPatch(...)`, `.ConflictsPatch(...)` for dependencies.
* `.Feature(...)`, `.NoFeature(...)` for [features](/doc/features-geboWdIiDN). The patch runs only in feature sets that have all `.Feature` ids on and all `.NoFeature` ids off. An id without a mod prefix is a feature of your mod.
* `.After(...)`, `.Before(...)`, `.AfterPatch(...)`, `.BeforePatch(...)` for ordering.
* `.Requires(predicate, message)`, `.Has(key, ...)`, `.HasNo(key, ...)` for gates.
* `.Do(...)` for the change.

The predicate in `.Requires` is typed: it receives the wrapper, so there is no cast.

```csharp
PM.PatchPart("BuffHeavyEngines")
    .Named("engine_*")
    .Requires(part => part["mass"] > 5.0, "not heavy enough")
    .Do(part => { /* ... */ });
```

Note `.Named("engine_*")`: the C# and Lua targeting both support `*` and `?` wildcards.

## Keeping and removing

`.Do` comes in two forms. The void form keeps the asset, like a Lua callback that returns nothing:

```csharp
.Do(part => part["mass"] = 0.0);
```

The form returning `PatchResult` lets you delete the asset, the equivalent of returning `"remove"` in Lua:

```csharp
.Do(part => SomeCondition(part) ? PatchResult.Remove : PatchResult.Keep);
```

## The attribute style

If you prefer declarative registration, mark a class with `[PMPatch]` and its patch methods with a per-domain attribute. PatchManager discovers them at load and registers each one. The modifiers (pass, targeting, dependencies, gates) are attributes too:

```csharp
using PatchManager.CSharpPatching;
using PatchManager.CSharpPatching.Attributes;
using PatchManager.Parts;
using PatchManager.Parts.UserData;

[PMPatch]
public class MyPatches
{
    [PatchPart]
    [Named("eva_kerbal")]
    public void FixKerbalTolerance(PartUserData part)
    {
        part["crashTolerance"] = 30.0;
    }

    [PatchPart]
    [Named("engine_*")]
    [Requires(nameof(IsHeavy), "not heavy enough")]
    public PatchResult BuffHeavyEngines(PartUserData part)
    {
        // ...
        return PatchResult.Keep;
    }

    private bool IsHeavy(PartUserData part) => part["mass"] > 5.0;
}
```

`[PMPatch]` derives your mod id from the assembly, or pass `[PMPatch("YourModId")]` to set it. The method takes the typed wrapper and returns `void` (keep) or `PatchResult`. A `[Requires]` or `[Has]` attribute names a sibling predicate method with `nameof`. Each available modifier attribute (`[Early]`, `[Late]`, `[First]`, `[Last]`, `[Named]`, `[NotNamed]`, `[Needs]`, `[Conflicts]`, `[Before]`, `[After]`, `[NeedsFeature]`, `[NoFeature]`, and the patch variants) has a fluent method with the same function. `[NeedsFeature("HardMode")]` is the attribute form of `.Feature("HardMode")`.

## Features

As with a Lua patch, each C# patch needs the default feature of your mod. Thus the patch runs only in campaigns that have your mod on. The patch scope also declares features and registers run callbacks. These are the C# equivalents of `PM:DefineFeature`, `PM:OnBeginRun` and `PM:OnEndRun`:

```csharp
public override void OnPreInitialized()
{
    PM.DefineFeature("HardMode", requires: new[] { "Ksp2Redux:Parts" });
    PM.OnBeginRun(set => _heavyParts.Clear());

    PM.PatchPart("HalveThrust")
        .Feature("HardMode")
        .Has("Module_Engine")
        .Do(part => { /* ... */ });
}
```

`OnBeginRun` and `OnEndRun` receive the set that PatchManager builds. They return an action that accepts `.Feature(id)` and `.NoFeature(id)`. Put the gate on the patch, not in an `if` around the patch. [Features](/doc/features-geboWdIiDN) gives the reason.

## Which style

Both produce identical patches: the attribute style is just declarative sugar over the fluent builder. Use the fluent style when you want patches built conditionally or in a loop, and the attribute style when your patches are static and you like them read as a list of declarations. Mix them freely.