Skip to content
Stephen Thiebaud edited this page Nov 18, 2025 · 2 revisions

IL Editing

There are many utilities to aid in composing IL edits.

Substitute

An ILCursor extension which allows you to conditionally substitute a value with another one given a predicate condition.

Refer to this DAYBREAK example:

private static void DrawSingleTile_SkipDrawingForLilyPads(ILContext il)
{
    var c = new ILCursor(il);

    c.GotoNext(MoveType.Before, x => x.MatchLdcI4(TileID.LilyPad));
    c.Substitute(TileID.LilyPad, type => TileLoader.GetTile(type) is ILilyPad { VanillaDrawTileInWater: true });
}

The above code matches to before TileID.LilyPad is pushed to the stack and conditionally replaces the value right before it with TileID.LilyPad if the tile is of the ILilyPad type. This is used to override a condition (type == TileID.LilyPad) to be type == TileID.LilyPad (true) for all TileLoader.GetTile(type) is ILilyPad { VanillaDrawTileInWater: true } (while preserving any checks that don't fulfill this condition). While it's used here to intercept a conditional branch, it can be used in any context where you want to replace a value given a condition.

AddVariable

An extension to ILCursor and related types which allows you to easily define a new local variable within a MethodBody. It returns the VaribleDefinition which may be directly used in APIs like ILCursor::EmitLdloc(VariableDefinition). It should be preferred to use the generic overload when possible, but you can pass a Type object directly as well.

Clone this wiki locally