-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial: Creating a custom Mod Settings Menu
The Mod Settings Menu is a new feature included in the LE1 Community Patch that allows you to customize some aspects of the game at runtime based on user preference. It is designed to match the functionality found in the mod menu in the LE3 Community Patch. The mod settings menu allows you to update plot bools and integers at any time within the game, which allows you to alter almost anything in game through custom sequences or dialogue checks. Just like the LE3 version, it is designed to be extensible by other mod authors to allow you to customize your own mod's behavior. If you have worked with the mod menu for LE3 before, you will find the functionality very similar, just with a different method of setting up your menu.
A set of template mod menu files can be found as an optional download in the LE1 Community Patch (NexusMods - scroll to the bottom, ModDB).
You should be familiar with the following concepts at a basic level before starting to work on a custom mod menu.
- Adding new strings to the game via a TLK table
- Plot management, specifically working with booleans and conditionals (see Introduction to Plot Management tutorial)
- The very basics of creating a custom UnrealScript class. You do not need to write any actual UnrealScript to make a mod menu
- Coalesced editing in LE1 through the M3CD coalesced delta feature
- Sequence editing, to allow your settings to affect the game
Note
A note on strings
Nearly all fields in the menu framework that display user-facing text, such as titles, descriptions, button text, etc, can be set as a TLK string reference, or by writing strings directly in the coalesced file (or default properties block). For example, in the submenu class, srTitle sets the string reference for the title of a submenu. An example value would be 200050, an id which references a string in the TLK table. The field sTitle is also available. This would let you set the title by editing the string in your coalesced instead of the TLK table. For example, directly writing "My Test Item" instead of ID 200050.
This tutorial will use sTitle and equivalents as it makes for a better example.
We recommend all user-facing strings be stored in the TLK table and referenced via the "sr" variant of the fields. This allows your mod to be localized to other languages in the future. The direct string fields can however be very useful when developing your mod to keep track of what is what. If your mod will never be localized into another language it may be easier to use the "s" variant of the fields.
If both an "sr" and an "s" value are provided to the same element, the direct string will override and be shown rather than the string reference.
Each mod using the mod menu will have it's own top level submenu. For some mods, like the LE1 Community Patch, this is all you will need. More complicated mods may require additional submenus nested within your mod's menu to better organize the settings. An extreme example would be Project Variety for LE3, which uses a large number of submenus to customize character appearances in nearly every scene of the game. Plan your submenu structure before you start creating menus.
As of ME3Tweaks Mod Manager 9.0, a starter kit option exists to set up your menu for you. This tutorial will show how to use this option. A collapsed section later on will show you how to create a settings menu by hand. This will be necessary if you ever want to create a nested submenu, or do anything a bit more complex.
You need to have a package file in your mod that contains all of your submenus. This should not be a level file. I would recommend this file being dedicated to your menu settings. For this example, this file is called TemplateMod_ModSettingsSubmenus.pcc and lives in my CookedPCConsole folder in my mod's DLC folder. Your package file should be called something else relevant to your mod. Mod manager will create this file for you.
Each submenu you create will be it's own class, a subclass of the ModSettingsSubmenu class that is shipped with LE1CP.
In the ME3Tweaks Mod Manager, right-click on your mod and select "Add starter-kit content to DLC mod". Click on "Add mod settings menu stub" and wait for the operation to complete. Once this is done, your menu has been created in your mod's DLC folder. If you open up the DLC folder, you will find a few new files have been created which will contain your menu and it's resources.

ConfigDelta-ModSettingsMenu.m3cd - The ConfigDelta file which installs your mod into the settings menu. Configure the "top-level" data for your mod here. You can also configure your entire menu from this file if you wish.
DLC_MOD_ExampleMod_ModSettingsSubmenus.pcc - Package file which contains the unique class for your mod submenu. You can configure your entire menu from this file, or from the coalesced delta file. Any nested submenus you create should also live in this file.
GUI_Images_DLC_MOD_ExampleMod.pcc - Package file which contains your menu images.
You will be editing these three files to customize the contents of your menu, and editing other vanilla game files to react to your settings.
If you would like to create a submenu by hand, a tutorial is available here.
Open up the ConfigDelta-ModSettingsMenu.m3cd file in a text editor.
The menu item options in this coalesced block must configured to your mod for the menu to be installed correctly. SubmenuClassName, at a minimum, needs to be correct for your menu to work at all. If you created your menu with the Mod Manager, everything will be working, but you will want to customize the strings to fit your needs.
The following settings are what ships with the starter kit, and should be customized as you see fit.
| Field Name | Description |
|---|---|
| SubmenuClassName | The in-memory path of the created top-level submenu class. This can be found in the metadata tab (In-Memory Path). If you use the mod manager stub, this will be properly filled out for you. |
| srCenterText | The TLK string ID for the name of this submenu. |
| srDescriptionTitleText | The TLK string ID for the header at the top of the description section for this submenu. |
| srDescriptionText | The TLK string ID for the description that will show up when you select this submenu. |
| Images | A list of in-memory paths for images that will show up when selecting this submenu. See the below section on Images. |
Note
The in-memory path is different from the instanced full path, as the instanced full path does not take into account the ForcedExport flag on package exports. For example, if your class was called "Submenu4" nested inside a package export called "MySubmenus" in the file "CoolModMenu.pcc", the path would be CoolModMenu.MySubmenus.Submenu4.
Other fields are available to add to this menu item if needed, see the full documentation on the menu item format below. These fields will only apply to the top level menu item for your mod - the entry point. All other settings will be configured on your own menu class that was created in the previous step.
Once this coalesced file is configured properly, you should now be able to apply your mod in the mod manager and see your menu installed, like the following image. This image uses the example stringrefs and images that are shipped in the template mod. The mod manager placeholder will have a slightly different set of example data. Editing the stringref of the matching field in the coalesced will update the text as shown.

Your submenu can be configured in one of two ways. Both methods work the exact same, but the method you use to edit it is up to you.
- You can directly modify the DefaultProperties object for your menu class. This method provides type safety and syntax highlighting, but it can be harder to work with outside of LEX. Once configured, you can also make any edits using the properties tab in the Package Editor.
- You can edit your custom class using Coalesced changes from your M3CD file. No syntax highlighting, but can be easier to copy and paste from outside of LEX. If you are used to working on Coalesced in LE2/3 you will be most familiar with this option.
This guide will use the Script Editor tab/properties to edit, as it provides syntax highlighting, but the data struct format would be the same for coalesced. An example of coalesced format will be shown at the end.

Your menu class itself has several fields that need to be set. Primarily, this is the Title and Subtitle fields that are shown at the top of the menu. The following fields are available for configuration on the ModSettingsSubmenu class:
ModSettingsSubmenu:
| Field Name | Data Type | Description |
|---|---|---|
| srTitle | TLK stringref | The title that will be displayed at the top of the menu |
| sTitle | string | Same as above |
| srSubtitle | TLK stringref | The subtitle that will be displayed at the top of the menu |
| sSubtitle | string | Same as above |
| defaultActionText | TLK stringref | The default action text that will be displayed on menu items that provide no action text. |
| menuItems | Array of ModSettingItemData | An array of all menu items that are in this menu |
The menuItems array will be populated with the settings for your mod, in the ModSettingItemData class format. The format for an item is listed below. You will likely not need every field for most menu items, no field is required.
ModSettingItemData:
| Field Name | Data Type | Description |
|---|---|---|
| srActionText | TLK stringref | The text of the action button that the user can press to apply this item |
| sActionText | string | Same as above |
| srLeftText | TLK stringref | Left justified text of this item's menu entry |
| sLeftText | string | Same as above |
| srCenterText | TLK stringref | Center justified text of this item's menu entry |
| sCenterText | string | Same as above |
| srRightText | TLK stringref | Right justified text of this item's menu entry |
| sRightText | string | Same as above |
| srDescriptionTitleText | TLK stringref | Text shown at the top of the description box for this item as a header |
| sDescriptionTitleText | string | Same as above |
| srDescriptionText | TLK stringref | Text shown in the description box for this item |
| sDescriptionText | string | Same as above |
| ApplySettingInts | Array of PlotIntSetting | An array of plot integer values that will be set upon the user applying this setting. See the "Working with Plot Ints" section below for more details |
| ApplySettingBools | Array of int | An array of plot bool ids that will be set upon this setting. A positive int will set that bool to true. A negative int will set that bool to false. |
| DisplayConditional | int | An ID of a plot conditional that will be used to determine if this menu item should be visible. True conditional means visible, false means not visible. A negative ID will flip that behavior. |
| DisplayBool | int | An ID of a plot conditional that will be used to determine if this menu item should be visible. True means visible, false means not visible. A negative ID would flip the bool to mean the inverse, false being visible. |
| DisplayInt | PlotIntSetting | Plot integer value that will be used to determine if this menu item should be visible. See "Working with Plot Ints" |
| EnableConditional | int | An ID of plot conditional that will be used to determine if this menu item should be greyed out or not. False is greyed out, true is enabled and usable. As above, negative ID flips the behavior. |
| EnableBool | int | An ID of plot bool that will be used to determine if this menu item should be greyed out or not. False is greyed out, true is enabled and usable. As above, negative ID flips the behavior. |
| EnableInt | PlotIntSetting | Plot integer value that will be used to determine if this menu item should be greyed out. See "Working with Plot Ints" |
| Images | Array of strings | A list of full instanced paths to images that will be displayed and can be cycled through when this setting is selected. Images need to be in SWF format. See "Working with Images" below |
| SubMenuClassName | string | The class name as a string of a submenu to be opened when this menu item is activated. Should be used when configuring in coalesced. |
| SubmenuClass | Class, subtype of ModSettingsSubmenu | The class of a submenu to be opened when this menu item is activated. Should be used when configuring in DefaultProperties |
| inlineSubmenu | bool | With this set to true, all menu items in the submenu associated with this class will instead be populated into the parent submenu. (They will be siblings of this menu item). Does nothing unless a submenu class is configured. This can be used to further organize your menu items from the development side. |
| disabled | bool | A direct boolean value to override whether this menu item should be greyed or not. True means greyed out. |
| hidden | bool | A direct boolean value to override whether this menu item should be hidden or not. True means hidden. |
| displayRequiredPackageExports | Array of strings | A list of fully instanced paths to determine if this menu item should be shown. If all the listed paths are loaded in game, the menu item will be visible. |
| comment | string | An unused field that you can use to write a comment for this menu item. Comment will not be user visible. |
This is how each of the text fields will show up in the mod menu:

Settings, and other actions that can take place, are represented as menu items within a submenu. The various plot variable settings, primarily the three Display fields and the three ApplySetting fields, are used to set and react to setting status. Each state of a setting will need to be represented as it's own menu item. Menu items can also be set to open additional submenus, which can help you further organize your settings.
Your top level mod menu that you installed into the coalesced at the start of the tutorial is, itself, a ModSettingItemData, so any of the available fields can also be applied to it.
A common setting that we will use as a basic example is a boolean mod setting that can either be on or off. The plot bool id that we want to set the state of is bool id 2079. For this setting, we will have two menu items.
One is the "off" state. When we press the button on this state, we want bool id 2079 to be set to true, as the user will "enable" it.
{
sLeftText = "Example Setting",
sRightText = "DISABLED",
sActionText = "Enable",
sDescriptionTitleText = "Description Title",
sDescriptionText = "Change Me!",
Images = ("GUI_MOD_TemplateMod.Images_Example"),
ApplySettingBools = (2079),
DisplayBool = -2079
},
The other is the "on" state, which will set the same plot variable to false when the button is pressed.
{
sLeftText = "Example Setting",
sRightText = "ENABLED",
sActionText = "Disable",
sDescriptionTitleText = "Description Title",
sDescriptionText = "Change Me! This setting is enabled.",
Images = ("GUI_MOD_TemplateMod.Images_Example"),
ApplySettingBools = (-2079),
DisplayBool = 2079
}
These two menu items typically would have similar text strings and images. By setting the DisplayBools to be the inverses of each other (the first is displayed when 2079 is false, the other when it is true), it will appear to the user to be one setting that has two states. Toggling the states will change the plot variable in the user's savegame.
This will result in a setting that looks more or less like the following and toggles the state of bool 2079:

Conditionals can be used to enable more advanced behavior. For example, you could configure a setting to be greyed out when playing as FemShep to create a setting that modifies BroShep's mesh.
Modders coming from LE2 and LE3 may find it easier to configure the mod settings menu through the .m3cd coalesced delta file, instead of default properties. The exact same data structures are used in either case. Below is a snippet from an .m3cd file that is used to configure a submenu with the exact same boolean example as was used above.
You will need to specify the package file and export path in the header of your coalesced section, as below. All field work the exact same. Ensure your DefaultProperties block is empty when configuring with this method.
[BioUI.ini TemplateMod_ModSettingsSubmenus.ModSettingsSubmenu_Template]
>sTitle="sTitle from coalesced"
>sSubtitle="sSubtitle from coalesced"
+menuItems=(sLeftText="Example Coalesced Setting", sRightText="DISABLED", sActionText="Enable", sDescriptionTitleText="Description Title", sDescriptionText="This setting is configured in coalesced! This setting is disabled.", Images=("GUI_MOD_TemplateMod.Images_Example"), ApplySettingBools=(2082), DisplayBool=-2082)
+menuItems=(sLeftText="Example Coalesced Setting", sRightText="ENABLED", sActionText="Disable", sDescriptionTitleText="Description Title", sDescriptionText="This setting is configured in coalesced! This setting is enabled.", Images=("GUI_MOD_TemplateMod.Images_Example"), ApplySettingBools=(-2082), DisplayBool=2082)Working with plot ints is the same as conditionals or booleans, but instead of just specifying the ID of the plot variable, you also need to specify the value you are looking for or want to set. Wherever a plot int will be referenced, the PlotIntSetting struct will be used.
PlotIntSetting:
| Field Name | Data Type | Description |
|---|---|---|
| Id | int | Plot Int id |
| Value | int | Desired plot int value |
For DisplayInt and EnableInt, the menu item will only be shown if the plot id matches the given value.
For ApplySettingInts, the menu item will set the given plot int to the given value.

Multiple images can be added to any menu item. Unfortunately, each image needs to be referenced in it's own SWF. You will need to have the JPEXS Flash Decompiler installed to configure images. I suggest having your own package file for images, however they can be in any file you'd like (just not a level file). Images must be in a 1024x512 resolution and be stored in DXT1 format.

In the latest Nightly versions of Legendary Explorer, a tool has been added to make creating mod settings images easier. Go to the Create menu and select "Create blank texture". When configured properly, this will generate a texture and properly referenced SWF for you in the current package file. The settings outlined in the following image must be followed to create a texture properly. The name you can change of course.

Once your texture is created, you can go to the Texture tab in Package Editor and select Import from File. Remember, your source image must be in a 1024x512 resolution.
You can load your images in your settings by using the in-memory path. A list of in-memory paths to the GfxMovieInfo export (not the texture export!) should be provided to settings as follows.
Images = ("GUI_MOD_TemplateMod.Images_MyImageThatIMade"),
In case you would ever like to create images manually, a tutorial is available here.
You can add additional submenus to your top level mod menu to provide additional control over the organization of your configuration options. For example, you could have a submenu to select one of many options for an integer plot var. Or, you could provide a menu that offers several specific options for a character's outfit.
To create a new submenu, you simply need to clone over the template submenu again into your Submenus file and rename the class to be unique as you did above. Then, configure this menu like normal.
To get into your new submenu from your top level mod menu (or any other menu), you simply need to set the SubmenuClass field on a menu item. Activating this menu item will then enter into your new submenu. If configuring your menus in UnrealScript, you can directly reference the class itself in the DefaultProperties block. With coalesced, you will instead need to set the SubMenuClassName field with the full instanced path + package name as you did above. The class name will be resolved to an actual reference to the class at runtime.

As part of a coalesced menuItem: SubMenuClassName="TemplateMod_ModSettingsSubmenus.MyNewSubmenu"
Sometimes you would like to configure your settings based on the presence of other mods. For example, in the Community Patch, some settings need to be disabled when LE1DP is installed, as that mod will override the settings behavior. The DisplayRequiredPackageExports feature allows you to do this.
The displayRequiredPackageExports property will accept a list of in-memory paths. If all of these exports are loaded in memory when the menu is opened, the setting item will be displayed. If at least one is not present, the setting item will not be visible. You can prepend each path with a "!" to invert the behavior, and only display if the export is not present in the game.
As above, please note the difference between in-memory path and fully instanced path. The ForcedExport flag matters in this scenario, and will affect the path.
You can use this to, for example, depend on the presence of a mod's GlobalTlk export, which is required for every DLC mod and will always be loaded in-memory by the game. A setting configured in this way will only be visible when that other mod is loaded.
For example, displayRequiredPackageExports = ("DLC_MOD_DiversityLE1_GlobalTlk.GlobalTlk_tlk") will configure the menu item to only be visible when the LE1 Diversity Project mod is installed. The community patch uses this feature to disable settings that are entirely overridden by LE1DP. Since the GlobalTlk file is always loaded in-memory when DiversityLE1 DLC folder is installed, the setting will be visible when the DLC is installed.
In the example of the Community Patch, the setting requiring LE1DP has disabled set to true, as the setting should not be configurable in that state. Both menu items that would allow you to configure the setting (when LE1DP is not present) need to have the inverse displayRequiredPackageExports setting applied, for example displayRequiredPackageExports = ("!DLC_MOD_DiversityLE1_GlobalTlk.GlobalTlk_tlk").
Since our setting states are simple plot variables, you can reference them anywhere the game interacts with the plot system. Typically, that is either going to be in level sequencing or conditionals. But you could in theory tie your settings into the quest system, dialogues, planet visibility, etc. We will not be going in depth on how these systems work as it's out of the scope of this tutorial.
To make "instant reloading" of settings work nicely in level files, the mod menu fires the remote event re_settings whenever it is closed. If your sequencing is programmed properly, this allows you to instantly see the result of, for example, a material swap that is applied by your setting, without reloading the game.

Any issues with this tutorial specifically (not with the template mod for example) can be opened in the issues tab of this repository with the documentation label. Issues with the mod settings menu or with the template mod should have the mod settings menu label applied.
This tutorial is a wiki page, so feel free to edit it to make things more clear, add missing details, etc. Your changes may be reverted if they do not match existing style or have improper grammar.