SilksongPrepatcher
General Preloader Patcher for Silksong Modding.
模組介紹 作者原文
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
安裝與使用 安裝:BepInEx 外掛
- 本站下載的壓縮包就是模組本體,通常是 BepInEx 外掛(解壓後得到 .dll 或外掛資料夾)。
- 建議流程:用社群模組管理器(如 r2modman)選中本遊戲後匯入該模組,管理器會自動裝好 BepInEx 前置並處理依賴。
- 手動流程:先在遊戲目錄裝好 BepInEx 載入器,再把解壓出的 .dll 或外掛資料夾放進 BepInEx/plugins/。
- 啟動遊戲,BepInEx 控制台會列印載入日誌;確認這個模組出現在日誌裡即為安裝成功。
帶「前置依賴」的模組需要一併安裝,否則不會載入。功能開關通常在遊戲內或外掛自帶的設定檔裡調整。
下面這些內容需要先安裝,否則該模組不會生效: