View on GitHub

rykz-spcm

An MCM equivalent for Skyrim Platform plugins.

Compatibility Guide

Introduction

This is a guide for plugin developers on how to make their plugin compatible with SPCM. This guide has two parts:

  1. How to properly implement Skyrim Platform’s settings API so that your plugin can handle hot-reloading.
  2. How to make an SPCM File to configure how your plugin’s settings will look in the SPCM menu.

If you’ve already implemented Skyrim Platform’s settings API properly (e.g. your settings file can be edited while the game is running), you can head straight to the SPCM File section.

Table of Contents

Settings API Implementation

To be added. The point is, your plugin has to be able to properly survive a hot reload and use Skyrim Platform’s settings API.

For now, refer to these:

SPCM File

Description

The SPCM file is a JSON file that you can use to provide additional information about the settings in your settings file. SPCM will look for SPCM files in the Data/Platform/SPCM folder. If your settings file is at Data/Platform/Plugins/X-settings.txt, you should make your SPCM file at Data/Platform/SPCM/X.json.

When a companion SPCM file is not found for a settings file, SPCM will only load settings with values of type number, boolean, or string. The name for each setting in the SPCM menu will be each setting’s key in the settings file. Type checking for user input will also be very limited, only ensuring that the input is of the same type with the values already in the settings file.

You can generate a template for a new SPCM file from an existing settings file with the SPCM File Generator.

File Structure

The general structure of an SPCM file is as follows:

[    ]  {
[  1 ]    "title": "Example Settings"
[  2 ]    "categories": {
[  3 ]      "category_hotkeys": {
[  4 ]        "title": "Hotkeys",
[  5 ]        "settings": {
[  6 ]          "key_menu": {
[  7 ]            "name": "Menu Key"
[  8 ]            "desc": "The key to open the menu"
[  9 ]            "type": "key"
[ 10 ]            "default": "27"
[    ]          },
[ 11 ]          ...
[    ]        }
[    ]      },
[ 12 ]      ...
[    ]    }
[    ]  }

Refer to the line numbers above for the following explanations.

Line Explanation
1 A string. The title of the menu that will show in SPCM.
2 An object. Each key has to start with “category_”, and the value should be a Category.
3 An example Category, with the key “category_hotkeys”.
4 A string. The title of the category that will show in SPCM.
5 An object. Each key has to also exist in the settings file and not start with “_”, and the value should be a Setting.
6 An example Setting, with the key “key_menu”. There should also be a “key_menu” in the settings file.
7 A string. The name of the setting that will show in SPCM. Optional, default is the key.
8 A string. The description of the setting that will show in SPCM. Optional, default is no description.
9 A string. The type of the setting that is used for input management and checking. Optional, but if not defined your setting may not be visible. Has to be valid according to the supported setting types.
10 A value of a supported type. The default value of the setting. Optional, default is no default value (user can’t reset setting to default). Has to be valid according to the setting’s type.
11 Zero or more other Settings.
12 Zero or more other Categorys.

Setting Visibility

Visibility Conditions

When an SPCM file is found, the SPCM menu will only show settings that:

When an SPCM file is not found, the SPCM menu will only show settings that:

Inferrable Value Types

Supported Setting Types

The following is a list of setting types that are currently supported by SPCM. Each section will include one or more examples.

The examples will include an example type string for that setting type and a default value with a type / structure that you can expect to receive in the actual settings file when a user modifies a setting of that setting type.

Action

Special type of Settings that doesn’t need an actual counterpart in the settings file.

It will show up as a button in SPCM that will send out a specific ModEvent when pressed.

Example Settings :

{
  ...
  "type": "action:Spawn,RykzChickenSpawner_Spawn"
  // will show as a button titled "Spawn" in SPCM, 
  // and will send out the "RykzChickenSpawner_Spawn" ModEvent when clicked
}

Example on how to receive the ModEvent in your plugin :

{
  // on plugin initialization, register the Player to receive the ModEvent
  // ensure this is only done once between hot reloads using SP's storage API
  const storagePath = `rykz-chicken-spawner-events-registered`;
  if (storage[storagePath] !== true) {
    const player = Game.getPlayer();
    if (player) {
      player.registerForModEvent(
        "RykzChickenSpawner_Spawn",
        "On_RykzChickenSpawner_Spawn"
      );
      storage[storagePath] = true;
    }
  }

  // on plugin initialization, add a hook for the event on the Player
  hooks.sendPapyrusEvent.add(
    {
      enter() {
        spawnChicken(); // actual code that runs when the button is pressed
      },
    },
    0x14,
    0x14,
    "On_RykzChickenSpawner_Spawn"
  );
}

Boolean

Booleans (true or false).

Example Settings :

{
  ...
  "type": "boolean",  // valid values are true and false
  "default": true
}

Decimal and Decimal Range

Decimals and ranges of decimals. For ranges, users will input with a slider with a customizable step size.

Example Settings :

{
  ...
  "type": "decimal",  // valid values are ONLY decimals
  "default": 3.5
}
{
  ...
  "type": "decimalrange:0.1,9.9",  // valid values from 0.1 to 9.9 (0.1 and 9.9 included)
  "default": 5.3
}
{
  ...
  "type": "decimalrange:0.1,9.9,0.3",  // valid values from 0.1 to 9.9 with 0.3 as slider step
  "default": 0.4
}

FormID

FormIDs that can be used in your plugin. The actual setting value will be a number, but users will input in hex form. Note that there are no lower nor upper bounds for the hex values: users can input whatever they like and it will only be converted into a number.

Example Settings :

{
  ...
  "type": "formid",  // valid values are valid Skyrim FormIDs
  "default": 622440
}

FormType

FormTypes that can be used in your plugin. The actual setting value will be a number, but users will input in a dropdown containing all available FormTypes.

Example Settings :

{
  ...
  "type": "formtype",  // valid values are valid Skyrim FormTypes
  "default": 42
}

Integer and Integer Range

Whole numbers and ranges of whole numbers. For ranges, users will input with a slider with a customizable step size.

Example Settings :

{
  ...
  "type": "integer",  // valid values are ONLY whole numbers
  "default": 3
}
{
  ...
  "type": "integerrange:1,10",  // valid values from 1 to 10 (1 and 10 included)
  "default": 3
}
{
  ...
  "type": "integerrange:2,20,2",  // valid values from 2 to 20 with 2 as slider step
  "default": 4
}

Key

DXScanCodes that can be used in your plugin. The actual setting value will be a number, but users will input with a key binding interface. Note that in addition to normal DXScanCodes possible values, 0 is also a possible value which will be set if users decide to unbind the key.

Example Settings :

{
  ...
  "type": "key",  // valid values are all valid DXScanCodes
  "default": 199
}

List

Lists of other supported types. Currently, types that can’t be in lists are list, map, and action.

Example Settings :

{
  ...
  "type": "list:number",  // valid values are lists of numbers
  "default": [
    4, 2, 0, 6.9
  ]
}

Map

Maps of other supported types to other supported types. Currently, types that can’t be in maps are list, map, and action.

Example Settings :

{
  ...
  "type": "map:string,number",  // valid values are maps of string to number
  "default": [
    ['bob', 29239],
    ['anne', 24.2]
  ]
}

Number

Numbers.

Example Settings :

{
  ...
  "type": "number",  // valid values are valid Javascript numbers
  "default": 1024
}
{
  ...
  "type": "number",  // valid values are valid Javascript numbers
  "default": 5.32
}

String

Strings.

Example Settings :

{
  ...
  "type": "string",         // valid values are valid Javascript strings
  "default": "Hello World"
}

Values

Single values that exists in a list that you provide. The actual setting value will be a string, but users will input with an autocomplete interface.

Example Settings :

{
  ...
  "type": "values:Left,Center,Right",  // valid values are Left, Center, and Right
  "default": "Left"
}