### Example .NET SDK Output Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/1_setup.html This is an example of the output you should see after successfully running `dotnet --list-sdks`, indicating at least one .NET SDK version is installed. ```text 6.0.1 [C:\Program Files\dotnet\sdk] ``` -------------------------------- ### Verify .NET SDK Installation Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/1_setup.html Run this command in your terminal to verify that the .NET SDK has been installed correctly. It should list the installed SDK versions and their locations. ```bash dotnet --list-sdks ``` -------------------------------- ### Install BepInEx Plugin Templates Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/1_setup.html Install the BepInEx plugin templates using the `dotnet new install` command. This command specifies the template version and the NuGet source to use. ```bash dotnet new install BepInEx.Templates::2.0.0-be.4 --nuget-source https://nuget.bepinex.dev/v3/index.json ``` -------------------------------- ### Install Core Fonts with Winetricks Source: https://docs.bepinex.dev/articles/advanced/proton_wine.html Run this command to install essential fonts required for Unity UI elements in games running under Wine. Ensure the WINEPREFIX environment variable is set if operating outside the default prefix. ```bash winetricks corefonts ``` -------------------------------- ### Generated Configuration File Example Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/4_configuration.html This is an example of a configuration file automatically generated by BepInEx based on the Bind calls in the plugin code. ```ini [General] ## A greeting text to show when the game is launched # Setting type: String # Default value: Hello, world! GreetingTest = Hello, world! [General.Toggles] ## Whether or not to show the greeting text # Setting type: Boolean # Default value: True DisplayGreeting = true ``` -------------------------------- ### Patcher Initializer and Finalizer Methods Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html Illustrates optional `Initialize` and `Finish` methods that can be included in a patcher class for setup and cleanup operations. ```csharp // Called before patching occurs public static void Initialize(); ``` ```csharp // Called after preloader has patched all assemblies and loaded them in // At this point it is fine to reference patched assemblies public static void Finish(); ``` -------------------------------- ### Basic Patcher Contract Example Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html A minimal example of a BepInEx preloader patcher class. It defines the target DLL and the patching method. ```csharp using System.Collections.Generic; using Mono.Cecil; public static class Patcher { // List of assemblies to patch public static IEnumerable TargetDLLs { get; } = new[] {"Assembly-CSharp.dll"}; // Patches the assemblies public static void Patch(AssemblyDefinition assembly) { // Patcher code here } } ``` -------------------------------- ### Configure Steam Launch Options for Linux Source: https://docs.bepinex.dev/articles/advanced/steam_interop.html Set the Steam launch option for Linux to execute the BepInEx script before the game starts. This ensures BepInEx is loaded correctly. ```bash ./run_bepinex.sh %command% ``` -------------------------------- ### Access and Use Configuration Values Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/4_configuration.html Read the current values of configuration entries using the .Value property. This example shows how to conditionally log a greeting based on a boolean configuration setting. ```csharp // Instead of just Debug.Log("Hello, world!") if(configDisplayGreeting.Value) Logger.LogInfo(configGreeting.Value); ``` -------------------------------- ### Get Current Working Directory Source: https://docs.bepinex.dev/articles/advanced/steam_interop.html Obtain the full path of the game folder on Unix-like systems. This path is required for configuring Steam launch options on macOS. ```bash pwd ``` -------------------------------- ### Execute BepInEx Run Script Source: https://docs.bepinex.dev/articles/user_guide/installation/index.html Run this command in the terminal within your game folder to start BepInEx. ```bash ./run_bepinex.sh ``` -------------------------------- ### Get Unity Version from BepInEx Log Source: https://docs.bepinex.dev/articles/advanced/debug/plugins_dnSpy.html Use BepInEx to log the Unity version of the game. This is crucial for selecting the correct dnSpy debug Mono package. ```log [Message: BepInEx] BepInEx 5.0.1.0 - [Info : BepInEx] Running under Unity v5.4.0.6710170 [Info : BepInEx] CLR runtime version: 2.0.50727.1433 ... ``` -------------------------------- ### Available BepInEx Project Templates Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/1_setup.html This table lists the BepInEx project templates available after installation, including their names, short names, languages, and tags, which help in identifying the correct template for your project. ```text Template Name Short Name Language Tags ------------------------------- ----------------------- -------- ------------------------------------------ BepInEx 5 Plugin bepinex5plugin [C#] BepInEx/BepInEx 5/Plugin BepInEx 6 .NET Core Plugin bep6plugin_coreclr [C#] BepInEx/BepInEx 6/Plugin/CoreCLR/.NET Core BepInEx 6 .NET Framework Plugin bep6plugin_netfx [C#] BepInEx/BepInEx 6/Plugin/.NET Framework BepInEx 6 Unity Il2Cpp Plugin bep6plugin_unity_il2cpp [C#] BepInEx/BepInEx 6/Plugin/Unity/Il2Cpp BepInEx 6 Unity Mono Plugin bep6plugin_unity_mono [C#] BepInEx/BepInEx 6/Plugin/Unity/Mono ``` -------------------------------- ### Declare Plugin Incompatibility Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Use the BepInIncompatibility attribute to prevent your plugin from loading if a specified incompatible plugin is present. The IncompatibilityGUID parameter takes the GUID of the plugin that should not be loaded alongside yours. ```csharp [BepInPlugin("org.bepinex.plugins.exampleplugin", "Example Plug-In", "1.0.0.0")] // If some.undesirable.plugin is installed, this plugin is skipped [BepInIncompatibility("some.undesirable.plugin")] public class ExamplePlugin : BaseUnityPlugin ``` -------------------------------- ### Create BepInEx Plugin Project Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Use the dotnet CLI to create a new BepInEx plugin project from a template. Replace with the target framework (e.g., netstandard2.0, net46, net35) and with the game's Unity version. ```bash dotnet new bepinex5plugin -n MyFirstPlugin -T -U ``` -------------------------------- ### Create a Custom ConfigFile Instance Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/4_configuration.html Manually create a new ConfigFile instance for use in non-plugin DLLs or preloader patchers. Use Paths.ConfigPath for the correct configuration directory. ```csharp // Create a new configuration file. // First argument is the path to where the configuration is saved // Second arguments specifes whether to create the file right away or whether to wait until any values are accessed/written var customFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "custom_config.cfg"), true); // You can now create configuration wrappers for it var userName = customFile.Bind("General", "UserName", "Deuce", "Name of the user"); // In plug-ins, you can still access the default configuration file var configGreeting = Config.Bind("General", "GreetingTest", "Hello, world!", "A greeting text to show when the game is launched"); ``` -------------------------------- ### Open Winecfg with Protontricks Source: https://docs.bepinex.dev/articles/advanced/proton_wine.html Use this command to open the graphical interface of protontricks, which allows you to manage Wine prefixes and run `winecfg` for a specific game. ```bash protontricks --gui ``` -------------------------------- ### Build the Plugin Project Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Compile your BepInEx plugin project using the dotnet CLI. Navigate to your project folder in the command line and run the build command. This generates the plugin DLL in the bin/Debug/ folder. ```bash dotnet build ``` -------------------------------- ### Configure Harmony Backend to Cecil Source: https://docs.bepinex.dev/articles/user_guide/troubleshooting.html If Harmony and MonoMod.RuntimeDetour encounter errors due to incomplete System.Runtime.Emit implementation, set 'HarmonyBackend' to 'cecil' in BepInEx.cfg. ```ini [Preloader] ## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend. ## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting. # Setting type: MonoModBackend # Default value: auto # Acceptable values: auto, dynamicmethod, methodbuilder, cecil HarmonyBackend = cecil ``` -------------------------------- ### Configure Steam Launch Options for macOS Source: https://docs.bepinex.dev/articles/advanced/steam_interop.html Set the Steam launch option for macOS using the full path to the BepInEx script. Replace `` with the actual game directory path obtained from the `pwd` command. ```bash "/run_bepinex.sh" %command% ``` -------------------------------- ### Creating a Log Source with Logger.CreateLogSource Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/3_logging.html A more concise method for creating and registering a ManualLogSource. This automatically handles the registration and provides a convenient way to log messages with a custom source name. Ensure to remove the source when done. ```csharp var myLogSource = BepInEx.Logging.Logger.CreateLogSource("MyLogSource"); myLogSource.LogInfo("Test"); BepInEx.Logging.Logger.Sources.Remove(myLogSource); ``` -------------------------------- ### Configure run_bepinex.sh for Steam Games Source: https://docs.bepinex.dev/articles/user_guide/installation/index.html Edit the `run_bepinex.sh` script to specify the game's executable name. This is necessary for Steam games. ```bash executable_name=""; ``` -------------------------------- ### Change BepInEx Entry Point for Unity 5 and Older (Option 2) Source: https://docs.bepinex.dev/articles/user_guide/troubleshooting.html An alternative entry point configuration for older Unity versions. This option uses UnityEngine.dll, Camera, and .cctor. ```ini [Preloader.Entrypoint] Assembly = UnityEngine.dll Type = Camera Method = .cctor ``` -------------------------------- ### Dynamic Target DLL Specification Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html Demonstrates how to dynamically specify target DLLs using an enumerator that can perform actions during patching. ```csharp public static IEnumerable TargetDLLs => GetDLLs(); public static IEnumerable GetDLLs() { // Do something before patching Assembly-CSharp.dll yield return "Assembly-CSharp.dll"; // Do something after Assembly-CSharp has been patched, and before UnityEngine.dll has been patched yield return "UnityEngine.dll"; // Do something after patching is done } ``` -------------------------------- ### Change BepInEx Entry Point for Unity 2017+ Source: https://docs.bepinex.dev/articles/user_guide/troubleshooting.html Adjust the entry point in BepInEx.cfg if the default is too early for BepInEx to load. Specify the assembly, type, and method for the new entry point. ```ini [Preloader.Entrypoint] Assembly = UnityEngine.CoreModule.dll Type = MonoBehaviour Method = .cctor ``` -------------------------------- ### Basic Plugin Logging with BepInEx Logger Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/3_logging.html Demonstrates the recommended way to log information, warnings, and errors within a BepInEx plugin using the Logger API. Ensure BepInEx is referenced in your project. ```csharp using BepInEx; namespace MyFirstPlugin { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin { private void Awake() { Logger.LogInfo("This is information"); Logger.LogWarning("This is a warning"); Logger.LogError("This is an error"); } } } ``` -------------------------------- ### Configure BepInEx to Load Dumped Assemblies Source: https://docs.bepinex.dev/articles/advanced/debug/assemblies_dnSpy.html Set these BepInEx configuration options to `true` to enable dumping and debugging of preloader-patched assemblies. Ensure the game is run once for the config file to be generated. ```ini LoadDumpedAssemblies = true BreakBeforeLoadAssemblies = true ``` -------------------------------- ### Advanced BepInDependency Usage Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Demonstrates various ways to specify plugin dependencies, including soft and hard dependencies, default hard dependency behavior, and version range constraints using node version range syntax. ```csharp [BepInPlugin("org.bepinex.plugins.exampleplugin", "Example Plug-In", "1.0.0.0")] // A soft dependency. Loading won't be skipped if it's missing. [BepInDependency("com.bepinex.plugin.somedependency", BepInDependency.DependencyFlags.SoftDependency)] // A hard dependency. Loading will be skipped (and an error shown) if the dependency is missing. [BepInDependency("com.bepinex.plugin.importantdependency", BepInDependency.DependencyFlags.HardDependency)] // If flags are not specified, the dependency is **hard** by default [BepInDependency("com.bepinex.plugin.anotherimportantone")] // Depends on com.bepinex.plugin.versioned version 1.2.x [BepInDependency("com.bepinex.plugin.versioned", "~1.2")] public class ExamplePlugin : BaseUnityPlugin ``` -------------------------------- ### Registering a Custom Log Source Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/3_logging.html Shows how to manually create and register a log source with BepInEx. This allows custom naming for log messages originating from specific parts of your plugin. Remember to remove the source when it's no longer needed. ```csharp var myLogSource = new ManualLogSource("MyLogSource"); // The source name is shown in BepInEx log // Register the source BepInEx.Logging.Logger.Sources.Add(myLogSource); myLogSource.LogInfo("Test"); // Will print [Info: MyLogSource] Test // Remove the source to free resources BepInEx.Logging.Logger.Sources.Remove(myLogSource); ``` -------------------------------- ### Define Plugin Configuration Options Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/4_configuration.html Bind configuration entries for plugin settings like text and toggles. These are typically defined in the Awake method of your plugin class. ```csharp using BepInEx; using BepInEx.Configuration; namespace MyFirstPlugin { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin { private ConfigEntry configGreeting; private ConfigEntry configDisplayGreeting; private void Awake() { configGreeting = Config.Bind("General", // The section under which the option is shown "GreetingText", // The key of the configuration option in the configuration file "Hello, world!", // The default value "A greeting text to show when the game is launched"); // Description of the option to show in the config file configDisplayGreeting = Config.Bind("General.Toggles", "DisplayGreeting", true, "Whether or not to show the greeting text"); // Test code Logger.LogInfo("Hello, world!"); } } } ``` -------------------------------- ### Change BepInEx Entry Point for Unity 5 and Older (Option 1) Source: https://docs.bepinex.dev/articles/user_guide/troubleshooting.html Modify BepInEx.cfg to use an alternative entry point if the default is too early. This option uses UnityEngine.dll, MonoBehaviour, and .cctor. ```ini [Preloader.Entrypoint] Assembly = UnityEngine.dll Type = MonoBehaviour Method = .cctor ``` -------------------------------- ### Add Game Libraries via NuGet Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Add game-specific libraries to your BepInEx plugin template by using the dotnet CLI. Replace 'GameName' with the actual game name as listed on the BepInEx NuGet feed. The '-v *' flag ensures compatibility with any version. ```bash dotnet add package GameName.GameLibs -v *-* ``` -------------------------------- ### Enable BepInEx Console Logging Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/1_setup.html Edit the `BepInEx.cfg` file to enable the console window for log output, which is useful for debugging. This setting is found under the `[Logging.Console]` section. ```ini [Logging.Console] ## Enables showing a console for log output. # Setting type: Boolean # Default value: false Enabled = true ``` -------------------------------- ### BepInPlugin with PluginInfo Helper Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Uses constants defined in a PluginInfo class for BepInPlugin attributes, often generated automatically from project configuration. This promotes consistency and easier management of plugin metadata. ```csharp [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] ``` -------------------------------- ### Reference Local Game Assembly Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Manually add references to game assemblies by editing your project's .csproj file. Replace 'MyAssembly' with the DLL name and provide the correct path to the DLL. It is recommended to copy game assemblies to a 'lib' folder in your project instead of referencing them directly from the game folder. ```xml path\to\MyAssembly.dll ``` -------------------------------- ### Patcher Method Signatures Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html Shows the valid signatures for the `Patch` method in a preloader patcher. The `ref` signature allows for replacing the entire assembly. ```csharp public static void Patch(AssemblyDefinition assembly); ``` ```csharp public static void Patch(ref AssemblyDefinition assembly); ``` -------------------------------- ### BepInProcess Attribute for Game Filtering Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Restricts plugin loading to specific game executables. The ProcessName parameter should include the '.exe' extension. This attribute can be specified multiple times to allow loading in several different games. ```csharp [BepInPlugin("org.bepinex.plugins.exampleplugin", "Example Plug-In", "1.0.0.0")] [BepInProcess("Risk of Rain 2.exe")] [BepInProcess("AnotherGame.exe")] public class ExamplePlugin : BaseUnityPlugin ``` -------------------------------- ### Basic BepInEx Plugin Structure Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html This C# code defines a basic BepInEx plugin. It includes the necessary using directive, namespace, the BepInPlugin attribute for metadata, and inherits from BaseUnityPlugin. The Awake method is used for plugin startup logic. ```csharp using BepInEx; namespace MyFirstPlugin { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin { private void Awake() { // Plugin startup logic Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); } } } ``` -------------------------------- ### Specify Target DLLs Dynamically Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html Use the TargetDLLs property to dynamically specify which assemblies to patch. This allows for pre-patcher work, such as reading configuration files, before returning the list of assemblies to be patched. ```csharp public static IEnumerable TargetDLLs { get { // Do whatever pre-patcher work... string[] assemblies = // Get asseblies dynamically (i.e from configuration file); return assemblies; } } ``` -------------------------------- ### Set Module Breakpoints in dnSpy Source: https://docs.bepinex.dev/articles/advanced/debug/assemblies_dnSpy.html Use dnSpy's Module Breakpoints window to specify module names for which execution should break upon loading. This allows for debugging dynamically loaded assemblies. ```csharp Debug > Windows > Module Breakpoints ``` -------------------------------- ### Add Execution Permission to BepInEx Script Source: https://docs.bepinex.dev/articles/advanced/steam_interop.html Grant execute permissions to the BepInEx run script on Unix-like systems. This is a necessary step before configuring Steam. ```bash chmod u+x run_bepinex.sh ``` -------------------------------- ### Global Plugin Logger Pattern Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/3_logging.html Implements the global plugin logger pattern to share a single logger instance across multiple classes within the same plugin. This requires a static field in the main plugin class to hold the logger. ```csharp using BepInEx; using BepInEx.Logging; namespace MyFirstPlugin { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin { internal static new ManualLogSource Log; private void Awake() { Log = base.Logger; } } } // Some other class in the plugin assembly class SomeOtherAssembly { public void SomeMethod() { Plugin.Log.LogInfo("Plugin message!"); } } ``` -------------------------------- ### Basic BepInPlugin Attribute Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Defines the essential metadata for a BepInEx plugin, including its unique identifier, human-readable name, and version. This attribute is mandatory for BepInEx to load the plugin. ```csharp [BepInPlugin("org.bepinex.plugins.exampleplugin", "Example Plug-In", "1.0.0.0")] public class ExamplePlugin : BaseUnityPlugin ``` -------------------------------- ### BepInDependency Attribute for Plugin Dependencies Source: https://docs.bepinex.dev/articles/dev_guide/plugin_tutorial/2_plugin_start.html Specifies dependencies on other plugins. The DependencyGUID is mandatory, while Flags (SoftDependency/HardDependency) and VersionRange are optional for controlling how missing dependencies are handled and which versions are compatible. ```csharp [BepInPlugin("org.bepinex.plugins.exampleplugin", "Example Plug-In", "1.0.0.0")] [BepInDependency("com.bepinex.plugin.important")] public class ExamplePlugin : BaseUnityPlugin ``` -------------------------------- ### Conditional Assembly Patching Source: https://docs.bepinex.dev/articles/dev_guide/preloader_patchers.html Within the Patch method, you can check the assembly's name to apply specific patching logic. This is useful when different assemblies require different modifications. ```csharp public static void Patch(AssemblyDefinition assembly) { if (assembly.Name.Name == "Assembly-CSharp") { // The assembly is Assembly-CSharp.dll } else if (assembly.Name.Name == "UnityEngine") { // The assembly is UnityEngine.dll } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.