Skip to content

Environment Construction

Synthesis

If you're coding within a Synthesis Patcher, you should not make your own environment as described here. Synthesis provides its own environment-like IPatcherState object in its Run function.

Synthesis State Object

Known Game Category

The simplest way to construct an environment if you know the game you want to target is:

using (var env = GameEnvironment.Typical.Skyrim(SkyrimRelease.SkyrimSE))
{
    // Use ISkyrimModGetter environment
}

Unknown Game Category

You can construct an environment when you don't know the target game:

using (var env = GameEnvironment.Typical.Construct(someGameRelease))
{
    // Use IModGetter environment
}

But this has the downside of not knowing the type of mod it will contain at compile time. This means it will only expose IModGetter objects, which will be harder to interact with, depending on your goals

Game Environment Builder

Lets you fluently tweak the environment that will be built to be customized to your needs:

  • Override the target Data folder
  • Wanting to omit a mod
  • Wanting to customize load order
  • Wanting to add an output mod, and integrate it with the link cache

These types of goals can be achieved with a builder:

var outgoing = new SkyrimMod(ModKey.FromFileName("MyMod.esp"), SkyrimRelease.SkyrimSE);
using var env = GameEnvironment.Typical.Builder<ISkyrimMod, ISkyrimModGetter>(GameRelease.SkyrimSE)
    .TransformLoadOrderListings(x => x.Where(x => !x.ModKey.Name.Contains("SkipMe")))
    .WithTargetDataFolder(someCustomDataFolderPath)
    .WithOutputMod(outgoing)
    .Build();

Transform Load Order

This gives you an Enumerable of mods, and lets you filter some out, or mix some in at your discretion.

TransformLoadOrderListings

This call gives you the listings as they appear in the load order files, before the mod objects get created. Ideally any trimming is done here, rather than after the mods have been created.

Order between multiple TransformLoadOrderListings is respected.

TransformModListings

This call gives you the listings after they have been transformed by any TransformLoadOrderListings calls, and after mod objects have been created for each listing. As such, this call can interact with the mod objects as part of its transform logic.

Order between multiple TransformModListings is respected, but will always come after any TransformLoadOrderListings calls.

WithOutputMod

This lets you mix in a mod that you plan on exporting content with. You can put multiple WithOutputMod calls in your builder chain.

Modifies Load Order

Using WithOutputMod adjusts the Load Order the Game Environment will give you, as described below

Load Order Trimming

When using WithOutputMod, be aware that this modifies the Load Order the environment will provide you to be trimmed so that it doesn't include the outgoing mod and anything after it. The Load Order presented by the environment represents the existing mods to consider while building the output mod, and as such, excludes the outgoing mod itself, and anything after it.

This is to help avoid:

  • "Collection modified while looping" errors
  • Adding masters to the outgoing mod from mods after itself in the load order (not allowed)

The Link Cache made by the environment with an output mod will include the Load Order mods PLUS the outgoing mod(s) at the end. Lookups against the Link Cache WILL resolve objects from your outgoing mod appropriately. Outgoing mods are registered in the Link Cache in a non-caching fashion, so edits to your outgoing mod will reflect in subsequent lookups appropriately.

Further Customization

If you want to break away from the default behaviors described above, you can always make your own Load Order and Link Cache objects that contain different content the way you want them. You can even opt to not use WithOutputMod entirely and have the Game Environment give you the whole Load Order as a baseline but customize it as you want from there.

WithTargetDataFolder

Allows you to customize what game folder the environment will be constructed against. Useful when dealing with ad-hoc installations.

WithLoadOrder

This is a TransformLoadOrderListings style call that simply discards any existing load order and injects an explicitly provided one. Will respect the ordering alongside other TransformLoadOrderListings phase calls.