Soft Dependencies

Updated 2 weeks ago

Usage

Soft Dependencies

In case you want to create a mod that optionally makes use of this library, I recommend implementing a soft dependency. This will allow people to play your mod even if they don't have this library installed, so people can have some more creative freedom.

To do this:

  • Make sure to still reference the assembly, as told under step 2 in Basic Pipeline
  • But, in your main Plugin Class, tell BepInEx to keep working even if it can't find STSharedAudioLib, by adding a DependencyFlag
    • [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
    • [BepInDependency("STSharedAudioLib", BepInDependency.DependencyFlags.SoftDependency)]
  • Then, on Awake(), set a public boolean to check if you have the game running with this library installed, with this block of code:
public static bool SharedAudioLibCompatible = false;

void Awake()
{
    SharedAudioLibCompatible = CheckForPlugin("STSharedAudioLib");
}

private static bool CheckForPlugin(string pluginName, bool printDebug = true)
{
    foreach (var plugin in Chainloader.PluginInfos.Values)
    {
        if (plugin.Metadata.Name == pluginName)
        {
            if (printDebug) Logger.LogInfo($"Successfully found {pluginName}");
            return true;
        }
    }
    if (printDebug) Logger.LogWarning($"Failed to find {pluginName}");
    return false;
}
  • This will go through all mods that BepInEx has already loaded, and by having a SoftDependency on STSharedAudioLib, we ensure that 1) STSharedAudioLib needs to load first so it shows up as "already loaded", and 2) your own mod will still work, even if STSharedAudioLib is not currently installed.
  • Then, whenever your patch happens, check whether bool SharedAudioLibCompatible is true, and fire a separate method that executes whatever you want to get from the SharedAudioComponent
[HarmonyPrefix, HarmonyPatch(typeof(AudioItem), "PlayAudio")]
public static void Prefix(AudioItem __instance)
{
    if (Plugin.SharedAudioLibCompatible) Plugin.PlayAudioClipFromPlaylist(__instance);
    else __instance.clipToPlay = SingleAudioClip;
}

public static void PlayAudioClipFromPlaylist(AudioItem __instance)
{
    __instance.clipToPlay = SharedAudioMethods.AudioClipGetNextInAudioList(__instance.clipToPlay,
    SharedAudioMethods.AudioListGetByName("My Extremely Hilarious Sounds",
    SharedAudioMethods.GetSharedAudioComponent(__instance.gameObject)));
}

IMPORTANT!! Every line of code that uses STSharedAudioLib methods as a soft dependency MUST be in a DIFFERENT method than for example your patches, since methods and variables seem to get pre-loaded once the method holding them starts. And if they aren't present because you don't have the mod installed, your game will most likely stop working!

  • Having it be in a different method that only gets called if SharedAudioLibCompatible is true, ensures that its SharedAudioMethods only get loaded if the library is actually available to load.
  • And then, in this separate method, execute whatever you want to do using the above Provided Methods, and you'll have the same capabilities as with a normal dependency.