Mod Settings - LaughingLeader-DOS2-Mods/LeaderLib GitHub Wiki

Table of Contents

Mod Settings Tutorial

This tutorial will guide you through registering settings to LeaderLib's Mod Settings GUI, located in the options menu.

Prerequisites

LeaderLib must be an active mod in the load order. Whether LeaderLib is a specific dependency or not is optional.

Additionally, lua scripting will be needed if you intend to retrieve the settings for your scripts. There's a tutorial here:

Lua Scripting Setup

Creating the ModSettingsConfig.json

Create a text file in this location, and name it ModSettingsConfig.json:

Divinity Original Sin 2\DefEd\Data\Mods\ModName_GUID\ModSettingsConfig.json

You can find a sample file here:
ModSettingsConfig.json

This file is automatically checked for when LeaderLib loads mod settings, in all active mods.

For the purpose of this tutorial, this will be the file's contents:

{
	"TitleColor": "#00FF00",
	"Data": {
		"Flags": [
			{
				"Type": "Global",
				"Entries": [
					"MYMOD_SomeGlobalFlag1",
					"MYMOD_TraderDisabled"
				]
			}
		],
		"Variables": {
			"NamePrefix": "MYMOD_Variable_",
			"Entries": {
				"SomeVariable1": {
					"Value": 10,
					"Min": 0,
					"Max": 100,
					"Increment": 1
				}
			}
		},
		"Buttons": [
			{
				"ID" : "MYMOD_AddItemsToPartyButton",
				"Callback": "Settings_AddItemsToParty",
				"HostOnly": true
			}
		]
	},
	"MenuOrder": [
		{
			"Name": "MYMOD_SettingsMenu_Section_General",
			"Entries": [
				"MYMOD_SomeGlobalFlag1",
				"SomeVariable1"
			]
		},
		{
			"Name": "MYMOD_SettingsMenu_Section_HostUtilities",
			"Entries": [
				"MYMOD_AddItemsToPartyButton"
			]
		}
	]
}

Top-Level Properties

Property Description Type
TitleColor An optional hex-code string, used to color the title font for the mod's name in the Mod Settings menu. string
Data This is a table of settings entries for the mod, divided into three groups: Flags, Variables, and Buttons. table
MenuOrder This is an optional array used to organize the settings entries into different categories. If not specified, the entries will be organized in the order that they're added. array

MenuOrder Properties

Property Description Type
Name The string key to use for the section title. Alternatively, the name can be a translated string handle. string
Entries An array of string IDs. The ID should be either a flag ID, variable ID, or button ID. The order of the IDs will be the order of settings in the GUI. array

Flags

Flag entries appear as checkboxes in the GUI. These are typically "Global" type flags, though a "User" flag type exist as well. These flags will be set or cleared when the global settings are loaded.

The GUI will use the flag's ID as a string key for the displayed name, and ID_Description for the tooltip. So MYMOD_SomeGlobalFlag1 would need to be a string key for the name, and MYMOD_SomeGlobalFlag1_Description for the tooltip text.

Reverse-Flags

If the flag ID has "Disabled" in the name, then the checkbox will be "checked" by default, and unchecking it will set the flag. For instance, we might name MYMOD_TraderDisabled as "Enable Trader" so in the GUI it's displayed as a checked box by default, but then if unchecked, our scripts will set our mod's trader off stage.

Flag Properties

Property Description Type
Type The flag type for the entries. "Global" or "User". string
Entries An array of flag ID strings. array
Settings A table that can be used to set properties on specific flags (or "All" for all entries), such as the "ClientSide" property. table

Variables

Variables appear as a slider in the GUI. The optional NamePrefix setting is used when determining the variable's display name and description. Like flags, it uses the ID as the name, and ID_Description for the tooltip.

Variable Table Properties

These are the properties for the parent table that holds all the variable entries.

Property Description Type
Entries An array of variable entries. array
NamePrefix An optional prefix to use when fetching each variable's name and description. string
DefaultMin An optional value to use for each entry's minimum value. number
DefaultMax An optional value to use for each entry's maximum value. number
DefaultIncrement An optional value to use for each entry's increment value. number
Settings A table that can be used to set properties on specific variables (or "All" for all entries), such as the "ClientSide" property. table

Each table entry in the "Entries" array can have these properties:

Variable Entry Properties

Property Description Type
Value The default value. number
Min The minimum value, used by the slider. number
Max The maximum value, used by the slider. number
Increment The amount to add or subtract from the value when moving along the slider. number

Buttons

Buttons allow you to call a specific function when pressed in the GUI. Unlock flags and variables, buttons don't have a parent table.

Button Entry Properties

Property Description Type
ID The button ID. string
Callback The global function name in the mod's ModTable. This can be within a subtable (i.e. MyCallbacks.SomeCallback), but making it a top-level global function is more reliable for avoiding an error. string
Enabled Whether the button is enabled by default. Defaults to true if not set. boolean
NamePrefix Optional prefix to use when determining the button's name and description. string
HostOnly Whether only the host can use this button. false by default. boolean

In the sample data, our button entry is this:

{
	"ID" : "MYMOD_AddItemsToPartyButton",
	"Callback": "Settings_AddItemsToParty",
	"HostOnly": true
}

The name string key would be MYMOD_AddItemsToPartyButton, and the description used for the tooltip is MYMOD_AddItemsToPartyButton_Description.

LeaderLib will look for a function named Settings_AddItemsToParty in our mod's global table on the client-side. As an example, say this code is in a script loaded by both BootstrapServer and BootstrapClient:

local _ISCLIENT = Ext.IsClient()

function Settings_AddItemsToParty()
	if _ISCLIENT then
		Ext.Net.PostMessageToServer("MyMod_Settings_AddItemsToParty", "")
	else
		local host = CharacterGetHostCharacter()
		ItemTemplateAddTo("061cbdb1-9d33-476b-9cc5-34cb14ecb1a3", host, 1, 1)
		ItemTemplateAddTo("0fe033a1-4216-455e-a2c8-74ae8019a4c6", host, 1, 1)
	end
end

if not _ISCLIENT then
	Ext.RegisterNetListener("MyMod_Settings_AddItemsToParty", function (channel, payload, user)
		Settings_AddItemsToParty()
	end)
end

The GUI will call Settings_AddItemsToParty on the client-side when the button is pressed.

Checking Settings with Scripting

With our ModSettingsConfig.json created, we can use scripting to react to values changing, or to retrieve the settings.

Retrieving Settings

First off, our settings table can be retrieved like so:

	local settings = Mods.LeaderLib.SettingsManager.GetMod(ModuleUUID)

SettingsManager.GetMod returns the ModSettings for a given UUID. We can use the global value ModuleUUID as a shortcut for our mod's UUID.

Next, we can retrieve flags and variables in the ModSettings.Global table like so:

local b = settings.Global:GetFlag("MYMOD_SomeGlobalFlag1", false)
local amount = settings.Global:GetVariable("SomeVariable1", 0)

The first parameter is the ID of the flag/variable, while the second is the "fallback" value to return if that entry is not found.

Subscribing to Changes

We can also subscribe to changes, like so:

Mods.LeaderLib.Events.ModSettingsChanged:Subscribe(function (e)
	if e.ID == "MYMOD_SomeGlobalFlag1" then
		if e.Value == true then
			
		else
		
		end
	elseif e.ID == "SomeVariable1" then
	
	end
end, {MatchArgs={ModuleUUID=ModuleUUID}})

This would call our function when settings from our specific mod changes, and we can further filter it down to the entry ID in MatchArgs, if desired (ID="MYMOD_SomeGlobalFlag1").

Events.ModSettingsChanged is called on both the client and server sides. If you intend to call Osiris functions when a setting changes on the server-side, you should check Ext.Osiris.IsCallable() first, as an entry may be updating before Osiris is "ready".

⚠️ **GitHub.com Fallback** ⚠️