Skip to content
Justin Swanson edited this page Jan 27, 2021 · 9 revisions

Starting Setup

If you used a Local Solution Patcher to Create a Patcher, then you will have a project that has a minimal basic setup:

public static int Main(string[] args)
{
    return SynthesisPipeline.Instance.Patch<ISkyrimMod, ISkyrimModGetter>(
        args: args,
        patcher: RunPatch,
        userPreferences: new UserPreferences()
        {
             ActionsForEmptyArgs = new RunDefaultPatcher()
             {
                 IdentifyingModKey = "YourPatcher.esp",
                 TargetRelease = GameRelease.SkyrimSE
             }
        });
}

public static void RunPatch(SynthesisState<ISkyrimMod, ISkyrimModGetter> state)
{
    //Your code here!
}

Main Method

The main method just passes the arguments given your program to the Synthesis systems, which handles all the various commands that could be passed in. Generally, the main method can be left as-is.

Run Patch Method

The RunPatch method is where the code for your patcher should be located. It will be run when Synthesis is running a pipeline, as well as when your program is started standalone. The method has access to the Synthesis State object, which has much of the information needed to run a patcher.

Whatever changes you want to be made should be applied to the state's PatchMod object.

Synthesis State Object

The state object given to your RunPatch contains several important objects:

  • PatchMod: The export patch mod object that all changes should be applied to
  • LoadOrder: Object containing all the readonly mod objects on the load order
  • LinkCache: Link Cache created from the load order
  • ExtraSettingsDataPath: Path where any custom Extra Input will be located

Typical Simple Code

Typical code for a Synthesis patcher consists of locating Winning Overrides for a record type, and adding them to the output patch mod with some changes. Here is a simplistic example:

// Loop over all the winning NPCs in the load order
foreach (var npcGetter in state.LoadOrder.PriorityOrder.Npc().WinningOverrides())
{
    // See if it is a Goblin 
    if (!npcGetter.EditorID?.Contains("Goblin", StringComparison.OrdinalIgnoreCase) ?? true) continue;

    // Add it to the patch
    var npc = state.PatchMod.Npcs.GetOrAddAsOverride(npcGetter);

    // Shrink
    npc.Height /= 2;
}

The above code will shrink any Goblin-named NPCs

Two good resources for learning further details:

User Preferences

The UserPreferences have an important default of ActionsForEmptyArgs which determines what will happen when your patcher is run outside the patcher pipeline. This is where you set what name you want to give the patch created when running straight from the IDE, as well as the target GameRelease:

  • ActionsForEmptyArgs:
    • IdentifyingModKey: What name to give the mod when run outside the patcher pipeline
    • TargetRelease: What GameRelease to use when run outside the patcher pipeline
  • IncludeDisabledMods: Whether to include mods that are disabled on the LoadOrder object (default false)
  • AddImplicitMasters: Whether to enable masters that are listed as disabled
Clone this wiki locally