Adding user options to your mod
Adding user options to your mod is a great way to allow users to configure or customize your mod in the Octos app:
In this guide, we will go through adding some user options to an example mod.
We need to add an options
field to our octos.json
file, which is where we'll specify the actual inputs to add, and then use the UserOptions
class of the Octos API to listen to changes in those settings by the user.
Adding user options
Recall that your mod can optionally include an octos.json
file in the root directory to specify metadata:
MyAwesomeMod/
├── index.html
├── octos.json
In our octos.json
, we can include the options
field to specify which options we want to add. For example, let's add a range slider for controlling the speed of something within our mod:
{
"name": "MyAwesomeMod",
"options": {
"speed": { // a range slider with ID 'speed'
"label": "My speed:", // the display name (required to render)
"type": "range",
"value": 5, // our default value
"step": 5, // the allowed interval between values
"min": 0, // the minimum allowed value
"max": 5 // the maximum allowed value
}
// you can add other options here
}
}
You can see an example of a slider UI in the image at the top of this page. To see all the different possible types of options you can add, see the octos.json reference.
A couple things to note in this example:
-
The keys of the
options
field correspond to IDs that we will use to refer to our options later in JavaScript -
A
label
is required for each option in order for it to render -
You can add as many options as you want from a wide range of potential inputs, including color pickers, number inputs, file selectors, checkboxes, dropdown menus, and more
Great! Now if you zipped your mod folder and installed it through the Octos app, you would see a new speed range appear in the sidebar when you click on your mod. Now, it's time to actually listen to changes in our speed range.
Listening to changes in user options
First, make sure to add the Octos API to your mod using one of the following methods:
Option 1: CDN (recommended)
Include this script tag in your HTML:
<script src="https://cdn.jsdelivr.net/npm/octos@latest/octos.min.js"></script>
Option 2: npm
You can also install the Octos API with npm:
npm -i octos
Option 3: direct download
Alternatively, you can download octos.min.js
from the source and include it directly in your wallpaper's source folder:
<script src="octos.min.js"></script>
Alright, now we can access the UserOptions
class in our JavaScript:
const userOptions = new octos.UserOptions();
Now, we can listen to our two user options events:
1) load
event: fired when your mod instance loads
2) change
event: fired when the user changes one of your options
For both of these events, we can use userOptions.on(event, callback)
. The callback
we pass to will be an event handler that recieves an {id, value}
object. This object includes the ID of the input that has been changed (or loaded), as we specified in our octos.json
and the new value of the option.
Let's add a handler for both of these events:
const userOptions = new octos.UserOptions();
let speedVariable = 0;
// make an event listener
const handleOptions = ({ id, value }) => { // an (id, value) pair is passed to both events
switch (id) {
case 'speed': // this is the id
speedVariable = parseInt(value) // it's good practice to convert it to an integer just in case
updateSpeed(); // do what we need with this new variable
break;
// add cases for other input ids
default:
break;
}
};
// register our event listener
userOptions.on('change', handleOptions)
userOptions.on('load', handleOptions)
Handling both the change
and load
events is often useful for separating how we handle initial user option values and then dealing with changes later, but in this example we didn't have a reason to separate them. In this case then, UserOptions
offers a handy changeload
event that lets us handle both events at once. We can use this single event handler in place of the last two lines of our previous example:
userOptions.on('changeload', handleOptions)
Well done! You've added a user option to your mod.
Another way
We could also handle user options events without needing to include the UserOptions
class or even the Octos API in our project. We do this by directly specifying onchange
and onload
events in our options
object. These allow us to give Octos a function to be called on these events. By default, the value
of the changed or loaded input is passed into the function we specify.
In this example, let's add a text option that will allow the user to select the background color.
Once again, we could separately specify handlers for onchange
and onload
events, but let's just combine them into the handy onchangeload
event.
Let's add our new background color picker to our octos.json
file:
"options": {
"url": {
"label": "Background color:",
"type": "color-picker",
"value": "#ffffff",
"onchangeload": "updateBackground"
}
...
}
Then in our index.js
:
function updateBackground(value) {
const backgroundColor = value;
document.body.style.backgroundColor = backgroundColor; // set background color
}
We can also use arrow functions to be a bit more concise:
"onchangeload": "(value) => document.body.style.backgroundColor = value"
This is similar to how you would add an onchange
event for an HTML element:
<input type="color" onchange="updateBackground()" />
In this example we didn't even need to include the Octos API to add functionality to our options, but there are some advantages to using the UserOptions
class.
Next steps
Check out the octos.json
documentation for the options
field to see the different types of input you can add.
Also see the UserOptions
reference to see more methods relating to user options, like dynamically getting and setting user options at any time.