Section 3: Mod Config Menu, If Statements, Concatenating Strings
Welcome back, today we're gonna learn about if statements, concatenating strings, and how to setup a mod config menu.
If Statements
An if statement will first check a condition and if the condition is true then all the lines of code under the if statement and before else/elseif/end
will execute.
A quick example, we can create an if statement here in the initializedCallback
to check if we have Ashfall, Crafting Framework, and Skills Module installed. And if not, tell the script to stop running.
Remember in the last episode, we imported these modules to our script using the include
function. So when the module is not found, it returns nil. This means if we don't have Ashfall installed, the ashfall
variable will be nil.
Since not nil
equals true
, the script will return and stop running. This is also called a nil check.
local function initializedCallback(e)
if not ashfall then
return
end
if not CraftingFramework then
return
end
if not skillModule then
return
end
event.register("Ashfall:ActivateBushcrafting:Registered",
registerBushcraftingRecipe)
This is an example code. We don't actually need them, as the dependency manager will do the same thing. We will discuss this in section 5.
Mod Config Menu
Another condition that we should check for is whether the mod is enabled or not. The common way to disable a MWSE mod is through the Mod Config Menu. So we need to add one for our mod.
To do that, register the "modConfigReady"
event outside of initializedCallback
. We can go to the doc page for "modConfigReady"
event and copy this template code to our main.lua.
local config = require("MyMod.config")
local function onModConfigReady()
local template = mwse.mcm.createTemplate({ name = "My Mod" })
template:saveOnClose("My Mod", config)
template:register()
local settings = template:createSideBarPage({ label = "Settings" })
settings.sidebar:createInfo({
-- This text will be on the right-hand side block
text = "My Mod v. 1.0\n\nCreated by me.\n\nHover over a feature for more info."
})
settings:createOnOffButton({
label = "Feature",
-- The text in the description will replace the text
-- in sidebar on the right-hand side, when this button
-- is hovered over.
description = "This feature does...",
variable = mwse.mcm.createTableVariable({
id = "feature",
table = config,
})
})
end
event.register(tes3.event.modConfigReady, onModConfigReady)
We need to change a few things here since right now this is a mod configuration menu for a mod called "My Mod".
First line here is loading another file, config.lua
, in the \MyMod
folder. This is a common way to load your config but since this is a relatively small mod, we can just load the config in main.lua
.
First, move the config variable as high as we can. And we will change local config = require("MyMod.config")
to this:
local configPath = "Craftable Bandage"
local defaultConfig = { enabled = true, logLevel = "INFO" }
local config = mwse.loadConfig(configPath, defaultConfig)
What this does is when the script gets configuration data from the config
variable, MWSE will try to load a json file in the config
folder with this configPath
name. If the file doesn't exist, it loads defaultConfig
table instead.
Let's use this enabled
config option in our initializedCallback
so it checks if the mod is enabled or not.
local function initializedCallback(e)
if not config.enabled then
return
end
Right now, the mod is always enabled because we don't have a way to disable it yet. So back to the MCM, replace all of the occurrences of ""My Mod"
" with ""Craftable Bandage""
.
I'll explain the template code a bit here. createTemplate()
paired with template:register()
is how you add a page in the Mod Config Menu.
saveOnClose()
is how your config gets saved in the json file. The first argument here is the configPath, the json file name that I mentioned before, and the second argument takes the config table.
createSideBarPage()
is how you get the two-column page for your MCM. You can also use createPage()
instead if you like a single-column page. If you choose to use the side bar page, usually we'll include some info on the right column using createInfo()
.
Concatenating Strings
So let's copy over our mod description here.
settings.sidebar:createInfo({
-- This text will be on the right-hand side column
text = "Craftable Bandage\n\nCreated by Amalie.\n\n" ..
"This mod allows you to craft OAAB bandages with novice bushcrafting skill." ..
"It serves as an alternative to alchemy and restoration",
})
You can see the description gets quite long there, so I use string concatenation to split them into multiple lines. To concatenate strings in Lua, use the double dot ..
between two strings. And here \n
means a new line.
Mod Config Menu (Continued)
Back to MCM, createOnOffButton
is the most used function and it's also how we create an enable/disable button for our mod. Let's change the label
to "Enable Mod".
description
is the text you'll see on the right column when the mouse hovers over the label and button. If your config option needs some explanation, this is how you add it. But an enable/disable button is pretty straight-forward, so I don't feel the need to specify that.
variable
is the variable you want to change by clicking the button. id
is the variable name. table
is the table the variable is in. We want to change the config.enabled variable by clicking on this button. The id
here should be enabled
and table should be config
.
In our case, we also need to set the restartRequired
field to true
so a message box will popup to warn the user. When the game first loads this script, if the mod is enabled, it registers the recipe, so it doesn't matter if we disable it in game.
settings:createOnOffButton({
label = "Enable Mod",
variable = mwse.mcm.createTableVariable({
id = "enabled",
table = config,
restartRequired = true,
}),
})
While you're at it, let's add a dropdown element to set the log level of our logger through MCM. Remember to also change the logLevel
to config.logLevel
when we create the logger using logging.new()
.
local log = logging.new({
name = "Craftable Bandage",
logLevel = config.logLevel,
})
...
})
settings:createDropdown({
label = "Log Level",
options = {
{ label = "TRACE", value = "TRACE" },
{ label = "DEBUG", value = "DEBUG" },
{ label = "INFO", value = "INFO" },
},
variable = mwse.mcm.createTableVariable({
id = "logLevel",
table = config,
}),
callback = function(self)
log:setLogLevel(self.variable.value)
end,
})
end
To test the MCM, you can change the "Registered bandage recipe" log to be a debug log. So now when we load the game and the logLevel
is set to "INFO"
, you should not be able to see this, but if you change it to "DEBUG"
, after a restart you should be able to see it again.
log:debug("Registered bandage recipe")
Let's launch the game to check if our mod config menu is registered successfully. You should be able to see the enable mod button and the log level setting dropdown.
That's it for today. It is encouraged that you play around with these settings to have a better understanding of how the mod gets disabled and enabled by pressing the button, and how the log level gets changed.
Today, you've learned what an if statement is, how to concatenate strings, and most importantly how to add a mod config menu to your MWSE mod.
What your main.lua should look like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
|