Skip to content

Create, Duplicate, and Override

Create New Records

New records can be constructed in a few ways. Note that a record's FormKey is required during construction, and immutable. If you want to change the FormKey of a record, a new one should be made. Any desired fields can be brought over via CopyIn mechanics.

By Constructor

Any standalone record can be made by using its constructor.

FormKey formKey = ...;
var potion = new Potion(formKey);

From a Mod's Group

If you have an IMod object that you want the record to originate from, you can easily make one from the corresponding Group.

var potion = mod.Potions.AddNew();

Claims Next Available FormKey

The new record will have the next available FormKey from that mod based on the metadata in its header, and automatically be added to the Group it originated from.

By Duplication

Duplicating a record is the equivalent of creating a fresh record, and then copying in data to match a different record. This can be done via CopyIn API, but there are some convenience methods for this as well

INpcGetter sourceNpc = ...;
ISkyrimMod myMod = ...;

var copy = myMod.Npcs.DuplicateInAsNewRecord(sourceNpc);
INpcGetter sourceNpc = ...;
ISkyrimMod myMod = ...;
FormKey formKey = ...;

var copy = myMod.Npcs.DuplicateInAsNewRecord(sourceNpc, formKey);
INpcGetter sourceNpc = ...;
ISkyrimMod myMod = ...;

var copy = myMod.Npcs.DuplicateInAsNewRecord(sourceNpc, "SomeUniqueEditorID");

Extra Requirements

If the supplied EditorID is not unique, it will throw an exception.

FormID Allocation

Overriding Records

It is very common to want to modify a record that is from another mod. This just entails making a copy of the original record and adding it to your output mod. The fact that the FormKey doesn't originate from your output mod implicitly means that it's an override.

GetOrAddAsOverride

The quick any easy way to override a record is to utilize a Group.GetOrAddAsOverride call. This will check if the record already exists as an override in your group, and return it if so. Otherwise, it will copy the source record to a new object, and add it to your mod for you.

INpcGetter sourceNpc = ...;
// Retrieve or copy-and-add the record to our mod
var overrideRecord = myMod.Npcs.GetOrAddAsOverride(sourceNpc);
// Modify the name to be different inside myMod
overrideRecord.Name = "My New Name";

Call After Filters to Avoid ITPOs

With this pattern, it is preferable to call GetOrAddAsOverride as late as possible, after all filtering has been done and you know you want to override and modify the record. This avoids adding records to your mod that have no changes.

Deep Copy Then Insert

This pattern is an alternative to GetOrAddAsOverride. It is sometimes preferable if it's hard to delay the GetOrAddAsOverride call, and you want more control over when a record actually gets added to the outgoing mod.

INpcGetter sourceNpc = ...;
// Make a new mutable object that is a copy of the record to override
var npcCopy = sourceNpc.DeepCopy();

// Modify the name
npcCopy.Name = "My New Name";

// Apply some late filter logic
if (!SomeFilter(npcCopy)) return;

// Add the record as an override after the filter
outputMod.Npcs.Add(npcCopy);

This strategy works well if you might change your mind and not add the copied record to the outgoing mod. It lets you get a mutable version of the record without adding it to your outgoing mod until you are certain you want to include it.

Nested Records

Some records like Placed Objects and Cells are often nested underneath other records. This makes it harder to follow the above patterns. For these you will want to make use of ModContext concepts.

Mod Contexts