SilksongPrepatcher

v1.4.0·Updated 2026-03-26

General Preloader Patcher for Silksong Modding.

About this mod Author’s original text

Silksong Prepatcher

Prepatcher with general purpose assembly modifications for Hollow Knight: Silksong.

PrepatcherPlugin

This plugin exposes events to monitor player data accesses, and control the value

received by the game without affecting the underlying save data.

To use, subscribe to either the PlayerDataVariableEvents.OnGetVariable or

PlayerDataVariableEvents.OnSetVariable events, where T is the field type.

The subscriber takes as arguments the player data object, the field name, and the

unmodified value (or the previous value if there are multiple subscribers), and

should return the modified value; in the GetVariable case the unmodified value

is the value of the field and the returned value is what the game code sees, and

in the SetVariable case the unmodified value is what the game code is trying to

set and the returned value is the value that is actually written.

For convenience, some common events have been added to the non-generic

PlayerDataVariableEvents class. These behave the same as the generic equivalent,

so PlayerDataVariableEvents.OnGetBool is the same as

PlayerDataVariableEvents.OnGetVariable, for example.

Example usage:

using GlobalEnums;

using PrepatcherPlugin;

// In your mod's Awake class

PlayerDataVariableEvents.OnSetBool += MonitorBoolSets;

PlayerDataVariableEvents.OnGetVariable += OnGetCaravanLocation;

// Defining the functions

private bool MonitorBoolSets(PlayerData pd, string fieldName, bool current)

{

Logger.LogInfo($"Setting bool {fieldName} to {current}");

// Make sure to return current if you don't want to modify the value that would be set.

return current;

}

private CaravanTroupeLocations OnGetCaravanLocation(PlayerData pd, string fieldName, CaravanTroupeLocations current)

{

// If the caravan is in the Marrow, make the game think it's in Greymoor. Otherwise no change.

return current == CaravanTroupeLocations.Bone? CaravanTroupeLocations.Greymoor: current;

}

For convenience, the PlayerDataAccess class exposes properties to get and set values from the

PlayerData.instance object while going via the above events (using the Get/Set functions defined in the unmodded code)

to maintain compatibility with mods that monitor save data accesses. For example, the following are equivalent:

bool b = PlayerData.instance.GetBool(nameof(PlayerData.hasBrolly));

PlayerData.instance.SetBool(nameof(PlayerData.hasWalljump), true);

and

bool b = PlayerDataAccess.hasBrolly;

PlayerDataAccess.hasWalljump = true;

Prepatcher

The following patches are made by the Prepatcher:

  • Route PlayerData field accesses through Get/Set variable funcs.

This has been done so that mods can more easily monitor when the game gets/sets

field values in the PlayerData, and control the output/effect of those accesses

through the events defined in the PrepatcherPlugin.

In particular, this allows for compatibility between mods that interact with

PlayerData in different ways.

  • Replace certain calls to Assembly.GetTypes with calls to safe methods.

In particular, the new method will not throw when types that are not loadable

are present in an assembly, and will ignore MMHOOK_ assemblies (which may contain

many types, none of which are of interest to functions defined in base game

assemblies).

To verify the changes the Prepatcher is making here are appropriate, check the following

without the Prepatcher installed (can be done easily with a simple MonoMod Hook):

  • Log the duration of the NestedFadeGroup.AddMissingBridgeComponents method in

TeamCherry.NestedFadeGroup.dll. This executes once during startup but is very

slow if the game has to check a lot of types from a lot of assemblies.

  • Log the duration of long (i.e. longer than 1ms) calls to ReflectionUtils.GetGlobalType

in PlayMaker.dll, particularly when entering scenes like Bone_04, Bone_10 and Greymoor_08

(among others). These specific cases are handled by the ReflectionUtilsPatcher, but

in general the GetTypes replacement will speed up the functions.

  • Replace c

Install & use Install: BepInEx plugin

  1. The archive from playbuff is the mod itself — usually a BepInEx plugin (a .dll or a plugin folder once unzipped).
  2. Recommended: use a community mod manager (such as r2modman) — pick this game, import the mod, and the manager sets up BepInEx and its dependencies for you.
  3. Manual route: install the BepInEx loader in the game folder, then drop the unzipped .dll or plugin folder into BepInEx/plugins/.
  4. Launch the game — the BepInEx console logs every plugin it loads; seeing this mod in the log means it is installed.

Mods with listed dependencies need those installed too, or they will not load. Options are usually changed in-game or in the plugin's config file.

Dependencies

Install these first, or the mod will not work:

BepInEx-BepInExPack_Silksong

File & checksum

Filename
SilksongPrepatcher-1.4.0.zip
File size
214.4 KiB
SHA-256
aac5f1e1b647ca298594a8ca5152602792f5bd9cbc55476a06dd21e5be9ca851
Stored at
2026-10-06 19:19