BepInEx basics
BepInEx finds your plugin, creates its Plugin component, and calls Unity lifecycle methods on it. The template uses Awake for startup:
private void Awake()
{
Logger = base.Logger;
Logger.LogInfo("My mod loaded!");
}Keep startup code small. If something fails in Awake, BepInEx may not finish loading the plugin.
Logging
The logger writes to the BepInEx console and BepInEx/LogOutput.log:
Logger.LogDebug("Useful while developing");
Logger.LogInfo("The mod loaded");
Logger.LogWarning("Something looks wrong");
Logger.LogError("The operation failed");Use Info for a few useful startup messages. Repeated messages, especially anything written every frame, should usually use Debug or be removed before release.
Configuration
BepInEx can create a configuration file for your plugin. Add this import:
using BepInEx.Configuration;Then bind an option in Awake:
private ConfigEntry<bool> _enabled;
private void Awake()
{
Logger = base.Logger;
_enabled = Config.Bind(
"General",
"Enabled",
true,
"Enable or disable the mod."
);
Logger.LogInfo($"Mod enabled: {_enabled.Value}");
}After the first launch, BepInEx writes the option to a .cfg file under BepInEx/config. The file name is based on the plugin GUID. Users can edit the file while the game is closed.
Configuration values are grouped into sections. In the example, General is the section, Enabled is the setting name, and true is its default value.
Unity lifecycle methods
BaseUnityPlugin inherits from Unity's MonoBehaviour, so the plugin can use normal lifecycle methods:
private void Update()
{
// Runs once per frame.
}
private void OnDestroy()
{
// Clean up event handlers or other resources here.
}Avoid expensive work and repeated logging in Update. Use OnDestroy to unsubscribe from events and undo anything that should not survive a plugin reload.
Plugin dependencies
If your mod requires another BepInEx plugin, declare it above the Plugin class:
[BepInDependency("author.requiredmod", BepInDependency.DependencyFlags.HardDependency)]Replace the example with the other plugin's GUID. A hard dependency prevents your plugin from loading when the required plugin is missing. This is separate from the dependency list in thunderstore.toml; published mods should declare the dependency in both places.
Useful directories
BepInEx exposes its main paths through Paths:
Logger.LogInfo(Paths.GameRootPath);
Logger.LogInfo(Paths.PluginPath);
Logger.LogInfo(Paths.ConfigPath);Use these properties instead of hard-coding a Steam installation path. They also work when the player uses a mod-manager profile.
Continue with Working with Unity Objects for components, lifecycle methods, coroutines, and scenes.