Skip to content

Mod Configuration Menu⚓︎

Mods can create new GUIs. One GUI that MWSE ships with is the Mod Configuration Menu. By registering into this system, mods can create settings pages for their mods in a place where users can easily find and manipulate them.

Note

The MCM API is an integration of the EasyMCM project. Users don't need to have EasyMCM installed to use the MWSE's MCM API. You can browse its predecessor EasyMCM's documentation here.

Simplest Example⚓︎

Below is the simplest code required to setup a mod config:

 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
local configPath = "My Awesome Mod" -- The name of the config json file of your mod

-- The config table
local config = mwse.loadConfig(configPath, {
    enabled = true
})

-- When the mod config menu is ready to start accepting registrations,
-- register this mod.
local function registerModConfig()
    -- Create the top level component Template
    -- The name will be displayed in the mod list on the lefthand pane
    local template = mwse.mcm.createTemplate({ name = "My Awesome Mod" })

    -- Save config options when the mod config menu is closed
    template:saveOnClose(configPath, config)

    -- Create a simple container Page under Template
    local settings = template:createPage({ label = "Settings" })

    -- Create a button under Page that toggles a variable between true and false
    settings:createYesNoButton({
        label = "Enable Mod",
        variable = mwse.mcm:createTableVariable({ id = "enabled", table = config }),
    })

    -- Finish up.
    template:register()
end
event.register(tes3.event.modConfigReady, registerModConfig)

After loading up the game, you should see "My Awesome Mod" in the mod config menu, with a Yes/No button with label "Enable Mod" in its configuration pane.

Advanced Examples⚓︎

Separate config.lua⚓︎

As your default config gets long, you might want to create a separate Lua file for it.

MyMod\config.lua

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
local configPath = "My Awesome Mod" -- The name of the config json file of your mod
local defaultConfig = {
    enabled = true,
    keybind = {
        keyCode = tes3.scanCode.k,
        isShiftDown = false,
        isAltDown = false,
        isControlDown = true,
    }, -- Ctrl + K
    nonEdible = {
        ["ingred_diamond_01"] = true,
        ["ingred_scrap_metal_01"] = true,
    }
}

return mwse.loadConfig(configPath, defaultConfig)

And we import the config with require function in the main.lua.

MyMod\main.lua

1
local config = require("MyMod.config")

MCM has a lot of features, and one of the most commonly used components is the Sidebar Page. When a component is moused over in a sidebar page, the right panel will display the description of that component. It is recommended to use a sidebar page instead of a page when a mod has lots of settings.

MyMod\main.lua

local settings = template:createSideBarPage({
    label = "Settings",
    -- This description will be displayed at the right panel if no component is moused over.
    description =
        "My Awesome Mod\n" ..
        "Version 1.0.0\n" ..
        "\n" ..
        "The mod is very awesome. And this is its awesome description.\n",
})

settings:createYesNoButton({
    label = "Enable Mod",
    -- This description will be displayed at the right panel if the button is moused over.
    description =
        "If this setting is enabled, the mod is enabled.\n" ..
        "\n" ..
        "If this setting is disabled, the mod is disabled.\n" ..
        "\n" ..
        "Default: yes",
    variable = mwse.mcm:createTableVariable({ id = "enabled", table = config }),
})

Key Binder⚓︎

If your mod adds any hotkey function, a way to rebind the hotkey in the mod config menu is a must.

MyMod\main.lua

settings:createKeyBinder({
    label = "Assign Keybind",
    description = "Assign a new keybind to perform awesome tasks.",
    variable = mwse.mcm.createTableVariable{ id = "keybind", table = config },
    allowCombinations = true,
})

Exclusions Page⚓︎

Let's say your My Awesome Mod makes certain ingredients non-edible. Using an Exclusions Page, you can allow users to manually add what ingredients should be non-edible in game.

MyMod\main.lua

template:createExclusionsPage({
    label = "Non-Edible Ingredients",
    description = "Ingredients that can't be directly consumed via equipping.",
    leftListLabel = "Non-Edible Ingredients",
    rightListLabel = "Ingredients",
    variable = mwse.mcm.createTableVariable{
        id = "nonEdible",
        table = config,
    },
    -- This filters the right list by ingredient object
    filters = {
        { label = "Ingredients", type = "Object", objectType = tes3.objectType.ingredient },
    },
})

There is also a more customized way to filter the right list. The following code filters the right list by ingredients with value higher than 100 gold.

MyMod\main.lua

    filters = {
        {
            label = "Ingredients",
            callback = function()
                local ingreds = {}
                --- @param ingred tes3ingredient
                for ingred in tes3.iterateObjects(tes3.objectType.ingredients) do
                    if ingred.value >= 100 then
                        table.insert(ingreds, ingred)
                    end
                end
                table.sort(ingreds)
                return ingreds
            end
        },
    },