-
Notifications
You must be signed in to change notification settings - Fork 0
ModRegistry
Namespace: ScavLib.mods
A registry for mod metadata and optional lifecycle wiring. Register your mod
so other mods and ScavLib tooling can discover it at runtime. As of v0.4.0,
you can also attach an IModLifecycle object to receive automatic callbacks
on world events. As of v0.5.0, each registration is backed by a ModSession
that you can query at runtime.
Call ModRegistry.Register() in your plugin's Awake():
using ScavLib.mods;
ModRegistry.Register(new ModInfo(
name: "MyMod",
version: "1.0.0",
description: "Does cool things.",
author: "YourName"
));ScavLib registers itself automatically on load.
Pass an IModLifecycle implementation as the second argument. ScavLib will
automatically wire its callbacks into the EventBus — you do not need to
call EventBus.Register() manually for the lifecycle object.
OnEnabled() is called immediately upon successful registration.
using ScavLib.mods;
using ScavLib.event_bus.events;
using ScavLib.util;
public class MyLifecycle : ModLifecycleBase
{
public override void OnEnabled()
{
ScavLibPlugin.Log.LogInfo("MyMod enabled.");
}
public override void OnWorldLoaded(WorldLoadedEvent e)
{
PlayerUtil.HealAll();
}
public override void OnLayerLoaded(LayerLoadedEvent e)
{
GameUtil.Log($"Entered layer {e.BiomeDepth}.");
}
}
// In your plugin's Awake():
ModRegistry.Register(
new ModInfo("MyMod", "1.0.0", "Does cool things.", "YourName"),
new MyLifecycle()
);See the Lifecycle System page for the full callback set.
| Field | Type | Description |
|---|---|---|
Name |
string |
Display name of the mod. |
Version |
string |
Version string, e.g. "1.0.0". |
Description |
string |
Short description of what the mod does. |
Author |
string |
Author name(s). Defaults to "Unknown" if omitted. |
VersionedDependencies |
VersionedDependency[] |
Structured dependencies with optional version ranges. |
Dependencies |
string[] |
Backward-compatible shim — returns dependency names only, derived from VersionedDependencies. |
ModInfo.ToString() returns "{Name} v{Version} by {Author}".
ModInfo provides several constructors that all chain to the most specific
one, so older 0.4.x call sites keep compiling:
// No dependencies
new ModInfo("MyMod", "1.0.0", "desc");
new ModInfo("MyMod", "1.0.0", "desc", "Author");
// Legacy string-array dependencies (0.4.x compat)
new ModInfo("MyMod", "1.0.0", "desc", "Author",
new[] { "ScavLib", "OtherMod" });
// Full versioned dependencies (0.6.0)
new ModInfo("MyMod", "1.0.0", "desc", "Author",
new[] { new VersionedDependency("ScavLib", minVersion: "0.7.1") });Dependencies are advisory only. A missing or version-mismatched dependency
logs a LogWarning at registration time but never blocks your mod from
loading. For actual load-order enforcement, use BepInEx's [BepInDependency]
attribute (see Getting Started).
VersionedDependency adds optional MinVersion / MaxVersion bounds on top
of a dependency name.
| Member | Type | Description |
|---|---|---|
Name |
string |
Dependency mod name. |
MinVersion |
string |
Optional inclusive lower bound, e.g. "0.6.0". |
MaxVersion |
string |
Optional inclusive upper bound. |
IsSatisfiedBy(string actualVersion) |
bool |
True if actualVersion falls within the range. |
// Require ScavLib 0.6.0 or newer
new VersionedDependency("ScavLib", minVersion: "0.7.1");
// Require a specific range
new VersionedDependency("OtherMod", "1.2.0", "1.9.9");Version strings are parsed loosely: any - or + suffix (pre-release / build
metadata) is stripped before comparison, and a bare "1" is treated as
"1.0". If a version string cannot be parsed, the check is skipped (treated
as satisfied) and a warning is logged rather than failing the registration.
VersionedDependency.ToString() renders the range for display:
- name only →
ScavLib - min only →
ScavLib (>=0.6.0) - max only →
ScavLib (<=1.9.9) - both →
ScavLib (0.6.0~1.9.9)
Declared dependencies appear in scavlib status:
MyMod v1.0.0 by Author [F] Deps: [ScavLib (>=0.6.0), OtherMod]
| Method | Returns | Description |
|---|---|---|
GetAll() |
IReadOnlyList<ModInfo> |
All registered mods, in registration order. |
TryFind(string name, out ModInfo info) |
bool |
Find a mod by name (case-insensitive). Returns the first match. O(1) lookup since 0.4.1. |
IsRegistered(string name) |
bool |
Quick check whether a mod with the given name is registered. O(1) since 0.4.1. |
HasLifecycle(ModInfo mod) |
bool |
true if the mod was registered with an IModLifecycle. |
GetLifecycle(ModInfo mod) |
IModLifecycle |
The lifecycle object, or null if none was registered. |
GetSession(string name) |
ModSession |
(0.5.0) The runtime session for a mod, or null if not registered. |
// Check if a dependency is loaded before using its features
if (!ModRegistry.IsRegistered("SomeDependencyMod"))
{
Logger.LogWarning("SomeDependencyMod is not installed. Some features disabled.");
return;
}
// Enumerate all mods
foreach (var mod in ModRegistry.GetAll())
GameUtil.Log(mod.ToString());
// Inspect a runtime session
var session = ModRegistry.GetSession("MyMod");
if (session != null)
GameUtil.Log($"{session.Info.Name} enabled={session.IsEnabled} " +
$"hasLifecycle={session.Lifecycle != null}");Internally, 0.5.0 migrated the registry to a ModSession-keyed store. A
ModSession is the runtime state of a registered mod and is returned by
GetSession(name).
| Member | Type | Description |
|---|---|---|
Info |
ModInfo |
The ModInfo this session represents. |
Lifecycle |
IModLifecycle |
The attached lifecycle object, or null. |
IsEnabled |
bool |
Whether the mod is currently enabled. Now: always true.
|
ModSession is a pure data structure in 0.5.0. The internal EventBus adapter
handle is retained on the session so the planned 0.5.1 enable/disable flow can
unregister cleanly, but no enable/disable operations are exposed yet.
In scavlib status output, mods registered with a lifecycle object are
annotated with [F] (think "Functional / lifecycle integration"):
Registered Mods (2):
MyMod v1.0.0 by YourName [F] Deps: [ScavLib]
LegacyMod v2.0.0 by Someone
LegacyMod above was registered with the basic Register(ModInfo) overload
and has no lifecycle — this is fully supported and backward compatible.
If a mod with the same name is registered more than once, a warning is logged
but both entries are kept in GetAll(). Only the first registration under
a given name enters the name-lookup index, so TryFind() / GetSession()
return that first one. Avoid registering the same mod name twice — dependency
lookups would otherwise be ambiguous.