Big Cheat Sheet
Overview
A massive list of code snippets without much contextual explaination.
Target Game
Most code snippets will assume Skyrim SE, but code should work for any game, generally.
Preparing the Examples
When ...
is seen, that generally means the example will not cover how that object might have been made. ...
is not actually valid code to be copied and pasted.
Missing Namespaces
If you're just copy pasting code, often it will not compile because some required namespaces are missing. You can have the IDE import them by clicking on the red object in question and activating quick fixes (Ctrl - .
in Visual Studio).
Construct an Environment
using var env = GameEnvironment.Typical.Skyrim(SkyrimRelease.SkyrimSE);
Console.WriteLine($"Data folder is: {state.DataFolderPath}");
Retrieve a Mod From a Load Order
if (myLoadOrder.TryGetValue("MyMod.esp", out var mod))
{
// ..
}
var mod = myLoadOrder["MyMod.esp"];
Construct a ModKey
var modKey = ModKey.FromFileName("Skyrim.esm");
if (ModKey.TryFromFileName("Skyrim.esm", out var modKey))
{
// If conversion successful.
}
else
{
// An unsuccessful conversion.
// Might occur if there was an extension typo, like "Skyrim.esz"
}
var modKey = new ModKey("Skyrim", ModType.Plugin);
Get List of Masters From A Mod
var masterCollection = MasterReferenceCollection.FromPath(pathToMod, GameRelease.SkyrimSE);
Console.WriteLine($"The mod {masterCollection.CurrentMod} has masters:");
foreach (var master in masterCollection.Masters)
{
Console.WriteLine($" {master.Master.FileName}");
}
using var mod = SkyrimMod.CreateFromBinaryOverlay(pathToMod, SkyrimRelease.SkyrimSE);
Console.WriteLine($"The mod {mod.ModKey} has masters:");
foreach (var master in mod.ModHeader.MasterReferences)
{
Console.WriteLine($" {master.Master.FileName}");
}
Look Up a Record
ILinkCache linkCache = ...;
var formLink = new FormLink<IFormListGetter>(FormKey.Factory("123456:Skyrim.esm"));
if (formLink.TryResolve(linkCache, out var foundRecord))
{
// Use the specific record we were looking for
}
Avoid Hand Writing FormKeys
Using the FormKey Generator project is a good alternative to hand constructing FormLinks"
Convert FormKey to FormID
=== MasterReferenceCollection
FormKey formKey = ...;
IMasterReferenceCollection masterCollection = ...;
FormID formID = masterCollection.GetFormID(formKey);
Convert FormKey to FormLink
FormKey formKey = ...;
// NOTE: Typically want to use the "getter" interfaces for FormLinks
var npcLink = formKey.ToLink<INpcGetter>();
Check if FormLink is Pointing to a Null record
Npc npc = ...;
if (!npc.Race.IsNull)
{
// ...
}
Convert FormLink to NullableFormLink
=== SetTo
IFormLinkGetter<IEquipTypeGetter> link = ...;
IFormLinkNullableGetter<IEquipTypeGetter> nullableLink = ...;
nullableLink.SetTo(link);
IFormLinkGetter<IEquipTypeGetter> link = ...;
IFormLinkNullableGetter<IEquipTypeGetter> nullableLink = link.AsNullable();
Convert MajorRecord to FormLink
INpcGetter npcGetter = ...;
var npcLink = npcGetter.ToLink();
Always use Getter interfaces
If the source major record type is not a getter interface it is recommended to take extra steps to keep the link targeting the getter interface
INpc npcSetter = ...;
var npcLink2 = npcSetter.ToLink<INpcGetter>();
// or
IFormLinkGetter<INpcGetter> npcLink3 = npcSetter.ToLink();
Iterate Winning Overrides
ILoadOrder<ISkyrimMod, ISkyrimModGetter> loadOrder = ...;
foreach (var keywordGetter in loadOrder.PriorityOrder.Keywords().WinningOverrides())
{
// Process each keyword record's winning override
}
ILoadOrder<ISkyrimMod, ISkyrimModGetter> loadOrder = ...;
ILinkCache linkCache = ...;
foreach (var cellContext in loadOrder.PriorityOrder.Cell().WinningContextOverrides(linkCache))
{
// Process each cell record's winning override
}
Iterate Original Definitions
foreach (var keywordGetter in loadOrder.ListedOrder.Keywords().WinningOverrides())
{
// Process each keyword record's original definition
}
Reasoning
By swapping to ListedOrder, the loop will now iterate over the original definitions of each record. By viewing the load order "backwards", is sees the original mods as the winning override to return
Override a Nested Record
FormKey someFormKey = ...;
ILinkCache linkCache = ...;
ISkyrimMod outgoingMod = ...;
var cellContext = linkCache.ResolveContext<ICell, ICellGetter>(someFormKey);
var overrideCell = cellContext.GetOrAddAsOverride(outgoingMod);
ILoadOrder<ISkyrimMod, ISkyrimModGetter> loadOrder = ...;
FormKey someFormKey = ...;
ILinkCache linkCache = ...;
ISkyrimMod outgoingMod = ...;
foreach (var cellContext in loadOrder.PriorityOrder.Cell().WinningContextOverrides(linkCache))
{
var overrideCell = cellContext.GetOrAddAsOverride(outgoingMod);
}
Check If A FormLink Points to a Specific Record
INpcGetter npc = ...;
if (Skyrim.Race.KhajiitRace.Equals(npc.Race))
{
}
INpcGetter npc = ...;
IFormLinkGetter<INpcGetter> formLink = ...;
if (target.Equals(npc.Race))
{
}
INpcGetter npc = ...;
FormKey formKey = ...;
if (formKey.Equals(npc.Race))
{
}
Duplicate a Record
Copy an existing record with a new FormKey
var dup = someRecord.Duplicate(newFormKey);
cs { .cs hl_lines="2" }
Npc someRecord = ...;
var dup = someMod.Npcs.DuplicateInAsNewRecord(someRecord);
FormKey desiredFormKey = ...;
var dup2 = someMod.Npcs.DuplicateInAsNewRecord(desiredFormKey);
string someUniqueEditorId = ...;
var dup3 = someMod.Npcs.DuplicateInAsNewRecord(someUniqueEditorId);
Detect if Given Plugin is the Winning Override for a Specific Record
There might be several ways to accomplish this, depending on the gritty situation, but here is one route:
// Use the link cache to locate the winning record, with additional context
if (formLinkOfRecordOfInterest.TryResolveSimpleContext(someLinkCache, out var context))
{
// The context's ModKey will be from the record that contained it
if (context.ModKey == givenPlugin.ModKey)
{
// givenPlugin was the winningmost override for the record!
}
else
{
// Some other mod is the winningmost override for this record: context.ModKey will have which one that is
}
}
Find all Major Record Types
foreach (var recTypes in MajorRecordTypeEnumerator.GetMajorRecordTypesFor(GameCategory.Skyrim))
{
Console.WriteLine($"Getter: {recTypes.GetterType}");
Console.WriteLine($"Setter: {recTypes.SetterType}");
Console.WriteLine($"Class: {recTypes.ClassType}");
}
Find all Major Record Types for Top Level Groups
foreach (var recTypes in MajorRecordTypeEnumerator.GetTopLevelMajorRecordTypesFor(GameCategory.Skyrim))
{
Console.WriteLine($"Getter: {recTypes.GetterType}");
Console.WriteLine($"Setter: {recTypes.SetterType}");
Console.WriteLine($"Class: {recTypes.ClassType}");
}
Enrich Exceptions
var majorRecordContext = ...;
try
{
// Access majorRecordContext and potentially throw
}
catch (Exception e)
{
throw RecordException.Enrich(e, majorRecordContext);
}
Call Generic Function by Mod Type
public class MyClass
{
public void DoSomeThings(IMod mod)
{
ModToGenericCallHelper.InvokeFromCategory(
this,
mod.GameRelease.ToCategory(),
typeof(MyClass).GetMethod(nameof(DoSomeThingsGeneric), BindingFlags.NonPublic | BindingFlags.Instance)!,
new object[] { mod });
}
private void DoSomeThingsGeneric<TMod, TModGetter>(TMod mod)
where TModGetter : IModGetter
where TMod : IMod, TModGetter, IMajorRecordContextEnumerable<TMod, TModGetter>
{
// Actual logic
}
}