Configurations
Configurations allow users to configure and customize your plugins behavior.
Assume your plugin gives XP when killing a player. By using configs, a user can dynamically set how much XP will be given.
OpenMod configurations are based on Microsoft.Extensions.Configuration which is also used in ASP.NET Core.
Warning
The <RootNamespace> and <AssemblyName> properties in the plugins .csproj file must be equal, otherwise the IConfiguration
service will not work.
Adding the config.yaml
Create a new file called "config.yaml" inside your project's root directory.
After that, add the following to your .csproj file:
<ItemGroup>
<EmbeddedResource Include="config.yaml" />
</ItemGroup>
Note
If you created your plugin project using one of the templates, the comfig.yaml file will be already set up.
Reading from the configuration file
You can use the IConfiguration
service to read the config.yaml file. You can inject it like this:
public class MyPlugin : OpenModUniversalPlugin
{
private readonly IConfiguration m_Configuration;
public MyPlugin(IConfiguration configuration, IServiceProvider serviceProvider) : base(serviceProvider)
{
m_Configuration = configuration;
}
public async Task OnLoadAsync()
{
// ...
}
}
Assume your configuration looks like this:
plugin_load_delay: 500
Then this is how you would read the value:
public async Task OnLoadAsync()
{
var delay = m_Configuration.GetSection("plugin_load_delay").Get<int>();
await Task.Delay(delay);
}
You can also have nested values:
plugin_load:
actions:
wait_delay: 500
public async Task OnLoadAsync()
{
// notice how ":" is used to access nested values
var delay = m_Configuration.GetSection("plugin_load:actions:wait_delay").Get<int>();
await Task.Delay(delay);
}
If you want to access strings, you can also use the indexer:
players:
owner: "Trojaner"
public async Task OnLoadAsync()
{
// reading strings is even easier
string owner = m_Configuration["players:owner"];
}
Warning
Configuration files are not meant store data, that's why there are no setter or save methods. See persistence if you need to store and load data.
Caution
Do not cache data read from configurations. This will break dynamic reloading of configuration files.
Converting configurations to C# classes
public async Task OnLoadAsync()
{
var config = new MyConfigClass();
m_Configuration.Bind(config);
// or if you only want to bind a subset:
// m_Configuration.GetSection("something").Bind(config);
}
Note
You can cache the config variable here, bind will automatically update the values if the config reloads.
Listening to configuration changes
To listen to changes, you can use change tokens.
Get the reload token of the configuration:
var changeToken = m_Configuration.GetReloadToken();
Add a new event listener:
var listener = ChangeToken.OnChange(() => reloadToken, () =>
{
m_Logger.LogInformation("Configuration file has been reloaded!");
})
You can use listener.Dispose() to stop listening.
Caution
Do not use config change listeners to fetch latest configuration values. OpenMod does this automatically. IConfiguration.Get will always return the current configuration values.
Adding your own configuration sources
You can add additional configuration sources by implementing the IConfigurationConfigurator
interface.
This interface allows you to add additional sources to the IConfigurationBuilder
used when building the OpenMod config.
Warning
Custom configuration sources for plugins are not supported yet.
Best Practices
Caution
Do not hardcode important values. If you are making a plugin that gives players XP when killing other players, make sure the XP amount is configurable, as it is something many users may want to adjust.
Caution
Do not overcomplicate your configurations. Only add values that users are likely going to change. Having a simple configuration is preferred to a complex one.
Caution
Do not use configurations for customizable messages. Use localization instead. Unlike configurations, localization supports formatting and passing arguments.