Skip to content

Configuration

Void exposes a configuration API that allows you to define in-file configuration options for your plugin.

To define configuration for your plugin, create any class with any parameters and default values.

class MySettings
{
public bool Enable { get; set; } = true;
public string? Name { get; set; } = "DefaultName";
public int Count { get; set; } = 0;
public Dictionary<string, string> Mapping { get; set; } = new()
{
["key"] = "value"
};
}

Inject IConfigurationService into your plugin or service constructor.
Then use GetAsync<T>() method to get the configuration instance.

public class MyPlugin(IConfigurationService configs) : IPlugin
{
[Subscribe]
public void OnPluginLoading(PluginLoadingEvent @event)
{
// This event is fired when any plugin is being loaded
// Skip all other plugins load events except ours
if (@event.Plugin != this)
return;
var settings = await configs.GetAsync<MySettings>(cancellationToken);
}
}

Now you can find this configuration file at configs/MyPlugin/MySettings.toml

configs/MyPlugin/MySettings.toml
Enable = true
Name = "DefaultName"
Count = 0
[Mapping]
key = "value"

It is possible to decorate configuration properties with ConfigurationProperty attribute.

public class MySettings
{
[ConfigurationProperty(Name = "ExampleName", InlineComment = "comment at the end of setting", PrecedingComment = "comment before setting")]
public bool ExampleValue { get; set; } = true;
}

Also you can set custom name for the configuration file with RootConfiguration attribute.

[RootConfiguration("settings")]
public class MySettings
{
public bool ExampleValue { get; set; } = true;
}

If you want to save multiple instances of the same configuration, you can use keyed configuration.
To save different settings per-player, use the following example:

public class MyPlugin(IConfigurationService configs) : IPlugin
{
[Subscribe]
public async ValueTask OnPlayerConnected(PlayerConnectedEvent @event)
{
var settings = await configs.GetAsync<MySettings>(@event.Player.Profile.Username);
}
}