Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Patcher pipelines

modde can run profile-scoped patcher stages as part of modde deploy. This is for generated patches that must match the current deployed files and active plugin load order. The first shipped stage type manages Synthesis CLI; the second runs a user-provided command with modde-owned environment variables.

Enabled patchers are required deployment artifacts. If an executable, settings file, Synthesis profile, runtime prerequisite, or command output is missing, deployment fails and prints the missing artifact, why it matters, how to regenerate it, and a validation command.

Synthesis

Synthesis remains an external tool. Install the .NET SDK, unpack all files from the Synthesis release zip into a dedicated tools directory, and create a PipelineSettings.json with Synthesis itself.

modde patcher add-synthesis synthesis \
  --profile my-skyrim \
  --game skyrim-se \
  --executable /tools/Synthesis/Synthesis.CLI.exe \
  --pipeline-settings /tools/Synthesis/PipelineSettings.json \
  --synthesis-profile my-skyrim \
  --output-mod synthesis-output \
  --order 10

During deploy, modde invokes:

Synthesis.CLI.exe run-pipeline \
  --OutputDirectory <deployed-data-dir> \
  --PipelineSettingsPath <PipelineSettings.json> \
  --ProfileIdentifier <profile> \
  --DataFolderPath <deployed-data-dir> \
  --LoadOrderFilePath <generated-load-order>

modde snapshots the deployed game mod root before and after the run, accepts only brand-new files plus rewrites of that stage’s own previous outputs, moves those files into ~/.local/share/modde/generated/<game>/<profile>/<stage>/, and then re-projects the managed output back into the game before the next stage runs. A stage that modifies base-deployed files or another stage’s output fails closed.

Command stages

Command stages are for local scripts or compiled patchers. modde sets these environment variables:

VariableMeaning
MODDE_PATCHER_DATA_DIRDeployed game data directory
MODDE_PATCHER_LOAD_ORDER_FILEGenerated active plugin load order
MODDE_PATCHER_PROFILEmodde profile name
MODDE_PATCHER_GAMEmodde game id
MODDE_PATCHER_STAGE_NAMECurrent patcher stage name
modde patcher add-command my-patcher \
  --profile my-skyrim \
  --game skyrim-se \
  --executable /home/me/bin/build-my-patch \
  --arg --strict \
  --env LOG_LEVEL=info \
  --output-mod my-patcher-output \
  --order 20

Managing stages

modde patcher list --profile my-skyrim --game skyrim-se
modde patcher validate --profile my-skyrim --game skyrim-se
modde patcher run --profile my-skyrim --game skyrim-se
modde patcher run synthesis --profile my-skyrim --game skyrim-se
modde patcher reorder synthesis my-patcher --profile my-skyrim --game skyrim-se
modde patcher disable synthesis --profile my-skyrim --game skyrim-se
modde patcher enable synthesis --profile my-skyrim --game skyrim-se
modde patcher remove my-patcher --profile my-skyrim --game skyrim-se

run executes the enabled pipeline against the currently deployed profile without performing a fresh base deploy first; pass a stage name to run just that stage. validate checks executables, settings files, and Synthesis profiles without running anything. reorder replaces the stage order with the supplied names.

Timeouts, caching, and failure recovery

Every stage has a hard timeout (default 1800 seconds; set per stage with --timeout-seconds on add-synthesis/add-command). A stage that exceeds it is killed and the run fails. Stage stdout/stderr are captured to log files so a killed or failed stage can be diagnosed after the fact.

Stage results are cached: when a stage’s settings, output mod, and the profile’s active load order are unchanged since its last successful run, the stage is skipped with Skipped patcher stage '<name>' (cache hit). Changing any input — including the load order — invalidates the cache.

Before a pipeline run, previously generated stage outputs are backed up; if the pipeline fails, they are restored, so a mid-pipeline failure does not leave the profile with half-regenerated patches.

Home Manager

programs.modde.profiles.my-skyrim = {
  game = "skyrim-se";
  patchers = {
    synthesis = {
      type = "synthesis-cli";
      enable = true;
      order = 10;
      outputMod = "synthesis-output";
      settings = {
        executable = "/tools/Synthesis/Synthesis.CLI.exe";
        pipelineSettings = "/tools/Synthesis/PipelineSettings.json";
        synthesisProfile = "my-skyrim";
      };
    };
  };
};

Home Manager configures patcher stages before it calls modde deploy. Deploy owns execution order and failure behavior.