lstwoMODS Core • Creating Mods

Mod Settings

Creating Mod Settings

A mod setting is similar to a mod action, but instead of calling a method, it sets a field.

[ModSetting]
public static float MySetting;

This will expose the float field in the UI and the user will be able to change it. You can now use this field for anything:

Plugin.Logger.LogInfo(MySetting);

But what happens when you change the field yourself:

MySetting = 2.5f;

The UI won’t immediately update unless your mods RefreshUI() was called. This method automatically gets called when the:

  • mods window the mod is in gets opened
  • mods window the mod is in get focused
  • mod itself gets opened

You can technically call this method yourself but it’s not standard practice and I’m not sure how well it works. Instead you can change the field from a float to a Ref<float>:

[ModSetting]
public static Ref<float> MySetting = new();

Always give the Ref a value, a Ref field left at null will throw when the UI gets built. You can pass a starting value to the constructor, e.g. new(1f).

Now you can use it like this:

MySetting.Value = 2.5f;
Plugin.Logger.LogInfo(MySetting.Value);

Setting this will automatically fire the MySetting.Changed event and for a mod setting this will automatically refresh it in the UI.

You can also create a mod setting from a property (the player stuff won’t actually work it’s just an example):

[ModSetting]
public static float PlayerSpeed
{
    get => Player.Speed;
    set => Player.Speed = value;
}

This turns Player.Speed into a mod setting, which will automatically update to it on RefreshUI and set it once the value changes.

Keep the getter safe to call at any time, it also runs while the panel is being built, which can happen before a game is loaded.

This begins to be more useful once the getters and setters aren’t simple fields:

public static float PlayerSpeed
{
    get
    {
        var player = GameManager.Instance.GetPlayer();
        return player.GetSpeed();
    }
    set
    {
        var player = GameManager.Instance.GetPlayer();
        player.SetSpeed(value);
    }
}

Obviously this can also be done manually using the Ref<float> parameters, by setting it in RefreshUI and subscribing to the Changed event, but using properties is much cleaner.

Customizing Mod Settings

Similarly to mod actions, mod settings can be customized:

[ModSetting(
    Label = "My Custom Setting",
    Min = -100,
    Max = 100,
    Format = "%.3f",
    Description = "A custom float mod setting",
    ShowInUI = true,
    Order = 10,
    Id = "CustomSetting",
    SeparatorText = "Mod Settings",
    Widget = WidgetType.Drag,
    Speed = 0.005f,
    ApplyButton = true,
    ApplyButtonLabel = "Apply Setting",
    Macroable = false
)]
public static Ref<float> MySetting = new();
  • Label: Label displayed on the input.
  • Min / Max: Min and max values for a number input.
  • Format: Printf format string for number values (e.g. “%.2f” for a float with 2 decimal places)
  • Description: Tooltip text displayed on hover.
  • ShowInUI: Whether or not the AutoUIBuilder should build UI for this setting. Set to false to make custom UI.
  • Order: What position this setting should appear at in the UI. Very important for mods with multiple actions and settings as otherwise they will be placed (sort of) randomly.
  • Id: An ImGui ID that should be pushed to the UI. Set this to something unique if ImGui complains about any Id conflicts due to multiple UI elements having the same name.
  • Separator: Whether there should be a separator line above this setting.
  • SeparatorText: Same as the one above but this one is a string that will be displayed as a SeparatorText. This works independently from the one above so setting this one to any non null value will enable it.
  • Widget: The widget type used for the input (Default, Drag, Slider, Input, Color3, Color4)
  • Speed (Drag type only): How much to increase the value per step.
  • ApplyButton: Whether or not it should have an apply button. If set to false it will auto set the value every time it changes.
  • ApplyButtonLabel: A label for the apply button.
  • Macroable: Whether or not to show this setting as a macro step.