Nivalis Mod Settings
A Mods tab in the game's own Settings window, plus a Mods menu button. Any BepInEx plugin can list its settings there with one API call.
By The_AsheR
| Last updated | 2 hours ago |
| Total downloads | 5 |
| Total rating | 0 |
| Categories | Mods AI Generated |
| Dependency string | The_AsheR-Nivalis_Mod_Settings-1.0.1 |
| Dependants | 0 other packages depend on this package |
This mod requires the following mods to function
BepInEx-BepInExPack_IL2CPP
BepInEx pack for IL2CPP x64 Unity games. Preconfigured and ready to use.
Preferred version: 6.0.788README
Nivalis Settings
A Nivalis Nights mod (BepInEx 6 IL2CPP). It adds a Mods tab to the game's Settings window, and a Mods button to the main and pause menus that opens Settings straight on that tab.
Any BepInEx plugin can list its ConfigFile settings in that tab with a single API call. The rows look like the game's own: sliders, toggles and left/right choices.
For players
- Install with r2modman or Gale, or manually drop
NivalisSettings.dllintoBepInEx/plugins(requires BepInExPack IL2CPP). - In game, open Settings → Mods, or press the Mods button in the menu.
Mods that support it: Nivalis Jump, Nivalis Bhop, Nivalis Parkour. Other plugins can be shown too with ShowAllPlugins (see below).
How the tab works:
- Changes apply immediately. They are written to the
.cfgfiles when you leave the tab or close the window. - Restore defaults resets every setting shown in the tab to its default value.
- To rebind a key setting, click its row and press the new key. Esc cancels.
The mod's own settings (BepInEx/config/com.asher.nivalissettings.cfg):
| Setting | Default | What it does |
|---|---|---|
Menu.MenuButton |
true |
Mods button in the main and pause menus |
Menu.ShowAllPlugins |
false |
Also list plugins that don't use the API, showing every entry of their config |
Debug.DumpUi |
false |
Write the Settings window hierarchy to the log, for debugging |
For mod authors
1. Reference the assembly
Reference the DLL from your .csproj without copying it into your build output: at runtime it is a separate plugin.
<ItemGroup>
<Reference Include="path/to/NivalisSettings.dll" Private="false" />
</ItemGroup>
Mod managers install it to BepInEx/plugins/The_AsheR-Nivalis_Mod_Settings/NivalisSettings.dll. On Thunderstore, add The_AsheR-Nivalis_Mod_Settings-1.0.1 to your dependencies only if your mod requires it (a soft dependency needs nothing there).
2. Register your settings
The simplest setup, where your mod requires NivalisSettings:
using NivalisSettings;
[BepInPlugin("com.me.mymod", "My Mod", "1.0.0")]
[BepInDependency(ModSettings.Guid)]
public class Plugin : BasePlugin
{
public override void Load()
{
var speed = Config.Bind("Movement", "Speed", 5f,
new ConfigDescription("Speed, m/s", new AcceptableValueRange<float>(1f, 20f)));
var enabled = Config.Bind("General", "Enabled", true, "Turn the mod on/off");
ModSettings.Register(this); // every entry of Config shows up in the Mods tab
}
}
3. Recommended: soft dependency
With a soft dependency your mod still works without NivalisSettings; it just has no menu. Keep every NivalisSettings type inside a separate method marked NoInlining. .NET then loads the assembly only when that method actually runs.
using System.Runtime.CompilerServices;
using BepInEx.Unity.IL2CPP;
[BepInPlugin("com.me.mymod", "My Mod", "1.0.0")]
[BepInDependency(NivalisSettings.ModSettings.Guid, BepInDependency.DependencyFlags.SoftDependency)]
public class Plugin : BasePlugin
{
public override void Load()
{
// ... Config.Bind(...) ...
if (IL2CPPChainloader.Instance.Plugins.ContainsKey(NivalisSettings.ModSettings.Guid))
RegisterSettings();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void RegisterSettings()
{
NivalisSettings.ModSettings.Register(this);
}
}
ModSettings.Guid is a constant that the compiler copies into your assembly, so [BepInDependency] and ContainsKey work even when the mod isn't installed. SoftDependency makes sure NivalisSettings loads before your plugin when it is installed.
4. Customize the page
Register returns a ModPage. Its methods return the same page, so you can chain the calls.
NivalisSettings.ModSettings.Register(this, "My Mod") // custom name instead of the [BepInPlugin] name
.Label(speed, "Run speed") // label instead of the key "Speed"
.SectionLabel("Movement", "Movement") // section title
.Hide(internalCounter) // don't show this entry
.HideSection("Debug") // don't show a whole section
.Button("Tools", "Reset stats", () => Stats.Reset())
.Order = 10; // position in the list, lower = higher up
API reference
ModSettings (static class)
| Member | Description |
|---|---|
const string Guid |
The plugin GUID, "com.asher.nivalissettings" |
ModPage Register(BasePlugin plugin, string displayName = null) |
Registers plugin.Config. The name defaults to the one in [BepInPlugin]. Calling it again returns the same page. |
ModPage Register(string id, string displayName, ConfigFile config) |
Registers any ConfigFile under a unique id, for example a mod's second config file. |
void Unregister(string id) |
Removes a page. For a plugin, id is its GUID. |
IReadOnlyList<ModPage> RegisteredPages |
All registered pages |
ModPage
| Member | Description |
|---|---|
string Id, ConfigFile Config |
Read-only |
string DisplayName |
Title of the mod's block in the tab |
int Order |
Block order: by Order first, then by name |
Hide(ConfigEntryBase entry) |
Hide an entry |
HideSection(string section) |
Hide every entry of a section |
Label(ConfigEntryBase entry, string label) |
Entry label. Defaults to the key with spaces added: BufferTime → Buffer Time. |
SectionLabel(string section, string label) |
Section title |
Button(string section, string label, Action onClick) |
A clickable row that calls onClick. The section is created if it doesn't exist. |
You can change a page after registering it, for example to show or hide an entry. An open tab rebuilds itself.
How entry types are shown
| Entry type | Control |
|---|---|
bool |
Toggle |
int, float, double |
Slider. Bounds come from AcceptableValueRange<T>; without one, it goes from 0 to 4× the default value. |
enum |
Left/right choice over all enum values |
any type with AcceptableValueList<T> |
Left/right choice over the listed values |
string whose key ends in Key, or whose value is a UnityEngine.InputSystem.Key name |
Key rebind: click, then press a key |
| anything else | Value shown read-only |
Tips:
- Give numbers an
AcceptableValueRange. Without one the slider bounds are guessed, and guessed badly. - Slider precision depends on the range. Values round to 0.001 for ranges up to 2, 0.01 up to 20, 0.1 up to 200, and whole numbers beyond that.
- Hide debug switches from players. Use
.HideSection("Debug"); they stay in the.cfgfor bug reports. - Write a
Descriptionanyway. It stays in the.cfgfor people who edit the file by hand. - Read
entry.Valueevery time you need the value. Then changes made in the menu take effect in game immediately. If you cache it, subscribe toentry.SettingChanged.
Order within a block
Sections appear in the order of your Config.Bind calls, and the Debug section always comes last. If a mod has a single section, its title isn't shown. Rows added with Button(...) go at the end of their section.
About
I wanted to tweak my mods right from the game instead of digging through .cfg files.
I made these mods with Claude (AI). Claude wrote the code; I came up with the ideas, played it over and over, broke things, and kept sending it back until it felt right. Have fun!