Table of Contents

Configs

Namespace: RisingV.Shared.Config
Assembly: RisingV.Shared

BaseConfig is an abstract helper that streamlines BepInEx configuration handling for your RisingV plugins and libraries.
It wires the entire configuration lifecycle—from creation to hot‑reload—while giving you a concise Bind helper and strongly‑typed accessors.

TL;DR – Derive from BaseConfig, override Log, declare your own config fields, and call Bind(...) inside Load().


At a Glance

Stage Method Typical responsibility
Construction BaseConfig(..) Capture file name / sub‑folder and call Start()
Start‑up trio Initialize() → Load() → Ready() Create the ConfigFile, bind your entries, run post‑load code
Hot Reload Reload(ReloadReason) Respond to external reload triggers (manual or on‑disk)
Tear‑down Unload() → Terminate() Release references and clear the file

Each step is virtual so you can extend (or skip) logic as needed.


Deriving from BaseConfig

public class MyPluginConfig : BaseConfig
{
    protected override Logger Log { get; } = LogManager.GetLogger<MyPluginConfig>();

    // Strongly‑typed handles
    public ConfigEntry<int>? SpawnRate { get; private set; }
    public ConfigEntry<string>? WelcomeMessage { get; private set; }

    public MyPluginConfig() : base("MyPlugin") { }

    public override void Load()
    {
        // Always call base.Load() – binds Enabled + queued entries
        base.Load();

        SpawnRate = Bind("Gameplay", "SpawnRate", 3,
            "Number of mobs spawned per wave");

        WelcomeMessage = Bind("UI", "WelcomeMessage",
            "Welcome, Vampire Lord!",
            "Text shown to newly connected players");
    }

    public override void Ready()
    {
        base.Ready();
        Log.Info($"SpawnRate={SpawnRate?.Value}  Message='{WelcomeMessage?.Value}'");
    }
}

File Placement Rules

<game root>/
└─ BepInEx/
   └─ config/
      └─ {ConfigRelativePath?}/
         └─ {ConfigFileName}.cfg
  • ConfigRelativePath (optional) – lets you group configs under sub‑folders (e.g. RisingV/Core).
  • ConfigFileName – pass without the .cfg extension; the class adds it automatically.

Built‑in Enabled Toggle

Every BaseConfig implementation automatically exposes:

public ConfigEntry<bool>? Enabled { get; private set; }

Use this flag to disable big chunks of functionality at runtime without removing the DLL.

if (Enabled?.Value is false) return; // early‑out

Helper Methods

Method Purpose
Bind<T>(section, key, default, desc) Wraps ConfigFile.Bind, but queues the request if the file isn't ready yet (e.g. called in constructor).
GetEntry<T>(section, key) Fetches the raw ConfigEntry<T>; returns null if missing.
GetValue<T>(section, key, default?) Convenience accessor returning the stored value or fallback.

Responding to Reloads

BaseConfig itself does not re‑load values automatically; it just provides the hook.

public override void Reload(ReloadReason reason)
{
    base.Reload(reason);

    // Re‑read dynamic settings
    Log.Info("Config hot‑reloaded – refreshing internal state");
    UpdateDifficulty(SpawnRate?.Value ?? 3);
}

Invoke your plugin’s Reload via:

  • In‑game command, or
  • Manually editing the .cfg and saving (if you have a file‑watcher).

Thread‑Safety Notes

  • ConfigFile operations are not thread‑safe.
  • Bind and access entries on the main thread or guard with locks if required.

Key Takeaways

  • Zero‑ceremony setup – just subclass and override.
  • Lazy bind queue ensures you can define configs even before Initialize().
  • Lifecycle hooks give you fine‑grained control over start‑up, shutdown, and reload.

Happy modding! 🦇