If you are looking to implement configurable keybindings, check out the Mod Key Bind Registry section on the Registry page.
SML adds a neat configuration system that allows you to easily define a config structure based on default values. These defaults can then be changed by the user, either from the in-game Mods menu, or via editing json files in their file system.
These configuration files are then loaded automatically on game boot and override the default values with the values specified by the user.
The mod can then access this configuration data to change its behavior depending on this static user input.
Using the Mod Configuration system
Create a new blueprint that extends ModConfiguration. Call it "<your mod reference>_Config" or similar.
Set the 'Mod Reference' to your mod reference and configure the display name and description as desired.
Set the Root Section to
BP Config Property Section
Your config items go in the Root Section’s "Section Properties" Left is the property name, right is the type If you want to have sub-categories in your config, use property type
BP Config Property Sectionagain. You can define custom widgets for your config properties if desired, otherwise SML will automatically select one for you based on the property type.
Right click on your configuration asset from the content browser
If you want your configuration accessible in C++, choose "Generate C++ Configuration Header," then save the header in your plugin’s source folders.
Next, select "Regenerate Configuration Structs," and SML will generate your mod’s config struct for you. Very convenient! Note that you will need to do this every time you make changes to your config.
You need to create a Game Instance Module for your mod, if you haven’t already made one yet, and specify your config under Mod Configurations there. Make sure to mark it as the root module if you’ve just made it.
Preview your Config
You can use the fancy SML Menu Preview Widget to view your mod config as it would appear in the game!
In a content browser, navigate to
SMLEditor Content/Menu Preview and right click on SML_MenuPreviewWidget,
then choose Run Editor Utility Widget. You should probably make the window fullscreen.
To look at your mod’s config in the previewer, select your ModConfiguration in the content browser, then press the Set Selected Mod Config button inside the preview window. Scroll down to see the config UI.
Interacting with the Config System in Blueprints
The following image shows how to interact with the Configuration System from Blueprints.
Below is a text explanation of the above image.
Creating a reference to your config
To interact with your config, you first need to create a reference to it:
Inside your blueprint, add a node called 'MC to ConfigProperty' and set the input class to your configuration’s class
From the node you just created, drag off the output pin and create a cast node to 'BP_ConfigPropertySection'
Creating a reference to a property
To create a reference to a property in your config, you will need a reference to a ConfigPropertySection. See the above section if you haven’t done so already
From the ConfigPropertySection, search for the node "To Section". The string input this node requires is the key of the property you want to retrieve
To get the value of a property from your config, you will need a reference to that property. See the above section if you haven’t done so already
Drag from the "To Section" node output pin and search for "CP to". This should list a number of "CP to " nodes followed by a type. Select the type of the config property you’re trying to get the value from. The output pin of the "CP to" node will give you the value of the config property.
If you have nested layers of Config Sections in your config, you can use another cast to 'BP_ConfigPropertySection', and then keep going as needed to get to the final value.
To set the value of a property from your config, you will need a reference to that property. See the "Creating a reference to a property" section above if you haven’t done so already
You first have to cast your property to the correct type. Drag from the "To Section" node output pin and search for "BP_ConfigProperty". This should list a number of cast nodes to different BP_ConfigProperty classes. Select the type of the config property you’re trying to get the value from.
From your Cast output pin search for "Set Value" and assign the new value you wish to set
Saving your config after changing a value
If you make a change to a config property from your code and want it saved, you must explicitly tell the configuration system to save changes. You’ll need a reference to your config; see the "Creating a reference to your config" section above if you haven’t done so already.
Drag from the output pin of the To Instance node you created and search for the function "Mark Dirty". This will save the whole config.
You can also save just one property if you want to. To do that, use the "Mark Property Dirty" function with the output from the "To Section" node as an input.
Check out the ExampleMod’s configs for a great demo of all the valid fields and how they appear in the editor. Be sure to check out the custom widget (with custom button) for something cool.
For a more detailed demonstration of how to read configuration values from Blueprint code,
check out how ExampleMod does it in
Interacting with the Config System in C++
This section was written while the SML Configuration system was still being developed. As such, these partially out of date, and are still being worked on. If you would like to use this system, see this message chain and ask on the discord for help.
If you are looking to implement configs with Blueprints, you should read about the helper functions provided by the SML Blueprint Interface and check out the ExampleMod.
The configuration manager is a engine subsystem that manages all configurations loaded into the game.
It will then be able to load and save registered configurations.
The registered mod configurations can get marked as dirty. This means that the user applied changes to the configuration values and that these changes need to be saved.
When loading a configuration, first the configuration value gets loaded based on default values. Then, or when the manager gets told to, it will load the configuration file, parse it and make the changes defined in these config files to the loaded configuration value.
It is important to differentiate between 'schema' and 'value' of the configuration. The Schema works like a class or declaration of how the configuration is structured and what attributes it has. The value is then basically the actual config values, which should be structured as described in the schema.
Reloads all registered mod configurations from disk. Optionally saving changes to the schema.
Marks the configuration referenced by the given ID as dirty and pending save.
FillConfigurationStruct(FConfigId ConfigId, <struct>)
Fills the passed struct with data obtained from the active configuration referenced by the given config id.
UUserWidget CreateConfigurationWidget(FConfigId ConfigId, UUserWidget Outer)
Creates a configuration widget hierarchy for the active configuration referenced by the given config id.
An identifier for a configuration consisting of the mod the configuration is part of and a category.
UModConfiguration is essentially the object that holds the whole schema of a configuration.
It works like a descriptor, meaning, the structure only needs to be defined in the class (aka default object) so we can simply reference the schema (aka mod configuration) by just passing the UClass around.
That means if you want to define your own configuration schema, you need to create new class based on this one. Then apply the changes (defining the schema itself and additional metadata) in the default values or the constructor.
A config property is essentially a node of a configuration schema, describing a specific value.
This used for creating the config value in the end.
Default values of child classes are also instancable, so you can further define the schema.
The short description of this property that is shown to the user when he hovers over the property.
Allows to retrieve the type of the configuration value the property is based on.
Fills the given config value object with the default value of this property.
UConfigValue CreateNewValue(UObject Outer)
Creates a new config value based on the type of this property and fills it with the default value defined by this property.
UUserWidget CreateEditorWidget(UUserWidget* ParentWidget)
Creates a widget instance that allows for editing config values described by this property.
Config Property Children
There are multiple classes inheriting
UConfigProperty describing a specific type of property.
There are classes for all main primitives like:
There are also two special ones that allow for more complex configuration structures.
A config value array allows you to store multiple values of the same type in a list.
For this you have the
ElementValue attribute, with which you can define the type of these list entries.
The list is dynamic, meaning, the amount of entries in the list can vary depending on what the user defined.
A config value section allows you to store multiple values of different types in one object.
For each entry you can have there is one property describing the type of this entry.
So with this you can basically have nested configurations allowing for more complex configuration structures.
UConfigProperty there is a value counterpart.
It essentially holds then a value described by the property.
Like the actual state, or… configuration loaded from the file / default values.
Converts the given value in the raw configuration format to the type of this value and stores it in this value object.
FillConfigStruct(FReflectedObject ReflectedObject, FString VariableName)
Fills the given config struct with the data provided by the referencing property and this value.
Gets called when the config value is initialized with the associated property.