### Initialize Mod Setup Function
Source: https://wiki.melvoridle.com/w/Mod_Creation/Getting_Started
The setup function must be exported from setup.mjs to be accessible by the Mod Manager.
```javascript
export function setup() {
console.log('Hello From My Mod!');
}
```
--------------------------------
### Define a setup entry-point module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
The setup function is required for the Mod Manager to initialize the mod. It receives the context object upon loading.
```javascript
// setup.mjs
export function setup(ctx) {
console.log('Hello World!');
}
```
--------------------------------
### Accessing Context from a Module Setup
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Use the exported setup function in your module to receive the context object as a parameter.
```javascript
export function setup(ctx) {
// ...
}
```
--------------------------------
### Define legacy extension manifest.json
Source: https://wiki.melvoridle.com/w/Mod_Creation/Migrating_from_Scripts_and_Extensions
Example of a previous extension manifest structure before migration.
```json
{
"icons": {
"48": "icons/my-icon-48.png"
},
"content_scripts": [
{
"js": ["sources/contentScript.js"],
"css": ["styles/mainStyle.css"]
}
]
}
```
--------------------------------
### Define Mod Manifest
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Configure the mod namespace and setup entry point in the manifest file.
```json
// manifest.json
{
"namespace": "helloWorld",
"setup": "setup.mjs"
}
```
--------------------------------
### Expose Mod API
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use the setup function to register methods to the mod API, making them accessible to other mods.
```javascript
// setup.mjs
export function setup({ api }) {
api({
greet: name => console.log(`Hello, ${name!}`);
});
}
```
--------------------------------
### Register Game Data Packages
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Methods for registering data packages via manifest or setup script.
```json
// manifest.json
{
"namespace": "helloWorld",
"load": ["path-to-your-data.json"]
}
```
```javascript
// setup.mjs
export async function setup({ gameData }) {
await gameData.addPackage('path-to-your-data.json');
}
```
--------------------------------
### Create a helper module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Helper modules export functions that can be imported and used by the main setup module.
```javascript
// helper.mjs
export function greet(name) {
console.log(`Hello, ${name}!`);
}
```
--------------------------------
### Create a PetiteVue component instance
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Defines a template, manifest entry, and setup function to mount a component to the DOM.
```html
{{ count }}
```
```json
// manifest.json
{
"load": ["templates.html"]
}
```
```javascript
// setup.mjs
function Counter(props) {
return {
$template: '#counter-component',
count: props.count,
inc() {
this.count++;
}
};
}
export function setup({ onInterfaceReady }) {
onInterfaceReady(() => {
// Create and append a Counter component to the bottom of the Woodcutting page
ui.create(Counter({ count: 0 }), document.getElementById('woodcutting-container'));
});
}
```
--------------------------------
### Implementing SettingTypeConfig functions
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Define the render, get, and set logic for a custom setting type.
```javascript
// The render function for a simple text box
function render(name, onChange, config) {
const input = document.createElement('input');
input.id = name;
input.type = 'text';
input.name = name;
input.addEventListener('change', () => onChange());
const label = document.createElement('label');
label.for = name;
label.textContent = config.label;
if (config.hint) {
const hint = document.createElement('small');
hint.textContent = config.hint;
label.appendChild(hint);
}
const validation = document.createElement('small');
validation.classList.add('text-danger', 'validation-message');
const root = document.createElement('div');
root.appendChild(input);
root.appendChild(label);
root.appendChild(validation);
return root;
}
```
```javascript
// get function for simple text input defined by above render
function get(root) {
return root.querySelector('input').value;
}
```
```javascript
// set function for simple text setting defined above
function set(root, value) {
root.querySelector('input').value = value;
}
```
--------------------------------
### Pass context to a helper module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Explicitly pass the context object from the setup function to helper modules that require it.
```javascript
// configService.mjs
export function init(ctx) {
// Perform actions using the context object here...
}
// setup.mjs
export async function setup(ctx) {
const configService = await ctx.loadModule('configService.mjs');
configService.init(ctx);
}
```
--------------------------------
### Define Mod Metadata
Source: https://wiki.melvoridle.com/w/Mod_Creation/Getting_Started
The manifest.json file provides essential metadata to the game, specifically pointing to the setup script.
```json
{
"setup": "setup.mjs"
}
```
--------------------------------
### Define a method patch
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Initialize a patch for a specific class method within the setup function.
```javascript
// setup.mjs
export function setup({ patch }) {
const xpPatch = patch(Skill, 'addXP');
}
```
--------------------------------
### Get and Set Setting Values
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Access or modify setting values at runtime using the get and set methods on a section object.
```javascript
// elsewhere.mjs
const { settings } = mod.getContext(import.meta);
const generalSettings = settings.section('General');
generalSettings.set('pick-a-number', 1);
console.log(generalSettings.get('pick-a-number')); // 1
```
--------------------------------
### Get and Set Setting Values
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves or updates the value of a specific setting by its name.
```javascript
// Assuming the player has typed "1" into the setting
ctx.settings.section('Other').get('pick-a-number'); // 1
```
```javascript
ctx.settings.section('Other').set('pick-a-number', 5);
```
--------------------------------
### Define an Item via JSON
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Example of defining a weapon item within a JSON data package.
```json
{
"$schema": "https://melvoridle.com/assets/schema/gameData.json",
"data": {
"items": [{
"id": "Wooden_Dagger",
"name": "Wooden Dagger",
"category": "Combat",
"type": "Weapon",
"media": "wooden-dagger.png",
"ignoreCompletion": false,
"obtainFromItemLog": false,
"golbinRaidExclusive": false,
"sellsFor": 0,
"tier": "wooden",
"validSlots": ["Weapon"],
"occupiesSlots": [],
"equipRequirements": [
{
"type": "SkillLevel",
"skillID": "melvorD:Attack",
"level": 1
}
],
"equipmentStats": [
{ "key": "attackSpeed", "value": 2200 },
{ "key": "stabAttackBonus", "value": 4 },
{ "key": "slashAttackBonus", "value": 1 },
{ "key": "blockAttackBonus", "value": 4 },
{ "key": "meleeStrengthBonus", "value": 1 }
],
"itemType": "Weapon",
"attackType": "melee"
}]
}
}
```
--------------------------------
### Registering a custom setting type with implementation
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Finalize the registration of a custom setting type by providing the required render, get, and set functions.
```javascript
// Use functions defined in above examples as reference
ctx.settings.type('simpleText', {
render: render,
get: get,
set: set
});
```
--------------------------------
### Get account storage item
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves the value associated with a key, returning undefined if the key does not exist.
```javascript
ctx.accountStorage.getItem('coolThings'); // returns ['rocks']
```
--------------------------------
### sidebar.category(id, config, builder)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Gets or creates a category by its ID, with optional configuration and a builder callback for adding items.
```APIDOC
## sidebar.category(id: string, config?: CategoryConfig, builder?: (category: Category) => void): Category
### Description
Gets or creates a category by its unique identifier. Optionally configures the category and executes a builder function to add items.
### Parameters
- **id** (string) - Required - The id of the category to get or create.
- **config** (CategoryConfig) - Optional - Configuration object for the category.
- **builder** (function) - Optional - Callback that receives the category instance for further modification.
### Returns
- **Category** - The category object.
```
--------------------------------
### PropertyPatch.replace(getter?: (o: () => any) => any, setter?: (o: (value: any) => void, value: any) => void)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
An alias for calling both get and set methods simultaneously on a property.
```APIDOC
## PropertyPatch.replace(getter?: (o: () => any) => any, setter?: (o: (value: any) => void, value: any) => void)
### Description
Alias for calling `get` and `set` at the same time.
### Parameters
- **getter** ((o: () => any) => any) - Optional - The getter function to be executed.
- **setter** ((o: (value: any) => void, value: any) => void) - Optional - The setter function to be executed.
```
--------------------------------
### subitem(id: string, config?: SubitemConfig, builder?: (subitem: Subitem) => void): Subitem
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Gets or creates a subitem by its ID, with optional configuration and builder callback.
```APIDOC
## subitem(id: string, config?: SubitemConfig, builder?: (subitem: Subitem) => void): Subitem
### Description
Gets or creates then gets a subitem by its id.
### Parameters
- **id** (string) - Required - The id of the subitem to get or create
- **config** (SubitemConfig) - Optional - An optional configuration object that may be used to configure either a new or existing subitem.
- **builder** ((subitem: Subitem) => void) - Optional - An optional callback that receives the subitem as a parameter
### Returns
- **Subitem** - The subitem object
### Example
```
// Move Pets above Skills in the Completion Log
sidebar.category('General').item('Completion Log').subitem('Pets', { before: 'Skills' });
// Add a shortcut to Alt. Magic beneath Magic
sidebar.category('Combat').item('melvorD:Magic').subitem('Alt. Magic', {
onClick() {
sidebar.category('Non-Combat').item('melvorD:Magic').click();
}
});
```
```
--------------------------------
### Render Component into UI
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use the ui.create helper to instantiate and mount the component to a DOM element.
```javascript
ui.create(Counter({ count: 0 }), document.getElementById('woodcutting-container'));
```
--------------------------------
### Build Data Packages at Runtime
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Dynamic registration of game objects using the mod context API.
```javascript
// setup.mjs
export function setup({ gameData }) {
gameData.buildPackage((p) => {
// use the `p` object to add game objects
}).add();
}
```
```javascript
// setup.mjs
export function setup({ gameData }) {
gameData.buildPackage((p) => {
p.items.add({
id: 'Wooden_Dagger',
name: 'Wooden Dagger',
category: 'Combat',
type: 'Weapon',
media: 'wooden-dagger.png',
ignoreCompletion: false,
obtainFromItemLog: false,
golbinRaidExclusive: false,
sellsFor: 0,
tier: 'wooden',
validSlots: ['Weapon'],
occupiesSlots: [],
equipRequirements: [{
type: 'SkillLevel',
skillID: 'melvorD:Attack',
level: 1
}],
equipmentStats: [
{ key: 'attackSpeed', value: 2200 },
{ key: 'stabAttackBonus', value: 4 },
{ key: 'slashAttackBonus', value: 1 },
{ key: 'blockAttackBonus', value: 4 },
{ key: 'meleeStrengthBonus', value: 1 }
],
itemType: 'Weapon',
attackType: 'melee'
});
}).add();
}
```
--------------------------------
### Patching Getter Properties
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Use the get method to intercept and modify the return value of a getter property.
```javascript
// Effectively double available Township resources
ctx.patch(TownshipResource, 'amount').get(function (o) {
return o() * 2;
});
// Or more practically, make resources unlimited
ctx.patch(TownshipResource, 'amount').get(function () {
return 999999;
});
```
--------------------------------
### ui.create(props: ComponentProps, host: HTMLElement)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Creates an instance of a PetiteVue component and mounts it within the specified HTML element.
```APIDOC
## ui.create(props, host)
### Description
Creates an instance of a component and mounts it within the HTML.
### Parameters
- **props** (ComponentProps) - Required - The PetiteVue component function that you want to instantiate.
- **host** (HTMLElement) - Required - The element that the component should be appended to.
### Returns
- **HTMLElement** - The host element.
```
--------------------------------
### ui.createStatic(template, host)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Creates an instance of a static component from a template and mounts it to a specified host element.
```APIDOC
## ui.createStatic(template: string, host: HTMLElement)
### Description
Creates an instance of a static component (no PetiteVue bindings) and mounts it within the HTML. This helper function should be preferred if you only need to create a reusable static piece of HTML.
### Parameters
- **template** (string) - Required - The selector string for the template you want to clone (e.g., '#my-static-component').
- **host** (HTMLElement) - Required - The element that the component should be appended to.
### Returns
- **HTMLElement** - The host element.
### Example
```javascript
// Create the static component and place it at the bottom of the Woodcutting page
ui.createStatic('#my-static-component', document.getElementById('woodcutting-container'));
```
```
--------------------------------
### Define Modifier in Data Package
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Example of registering a new modifier within a game data package.
```json
{
"$schema": "https://melvoridle.com/assets/schema/gameData.json",
"namespace": "myNamespace",
"data": {
"modifiers": [
{
"id": "flatSkillInterval",
"inverted": true,
"modifyValue": "value/1000",
"allowedScopes": [
{
"scopes": {},
"descriptions": [
{
"text": "${value}s Global Non-Combat Skill Interval",
"lang": "MODIFIER_DATA_flatSkillInterval"
}
]
}
]
}
]
}
}
```
--------------------------------
### Create Mod Settings Sections
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Initializes settings sections which determine the display order in the mod settings window.
```javascript
ctx.settings.section('General');
ctx.settings.section('Other');
// Sections will be displayed in the settings window in this order
// 1. General
// 2. Other
```
--------------------------------
### Import HTML Templates
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Import templates via manifest configuration or the loadTemplates helper function.
```json
{
"load": "templates.html"
}
```
```javascript
export function setup({ loadTemplates }) {
loadTemplates('templates.html');
}
```
--------------------------------
### Create a Component Instance
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Mounts the defined Block component into a specific DOM element.
```javascript
ui.create(Block({
header: { title: 'My Block Component' },
content: { lines: ['My first paragraph.', 'My second paragraph.'] }
}), document.getElementById('woodcutting-container'));
```
--------------------------------
### Build and Register a Game Data Package
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Constructs a package using the builder API and registers it.
```javascript
ctx.gameData.buildPackage((p) => {
// data registration here
});
```
```javascript
const pkg = ctx.gameData.buildPackage((p) => { /* ... */ });
pkg.add();
```
--------------------------------
### Create Mod Setting Sections
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use the section method to initialize or retrieve a settings section header.
```javascript
// setup.mjs
export function setup({ settings }) {
// Creates a section labeled "General"
settings.section('General');
// Future calls to that section will not create a new "General" section, but instead return the already existing one
settings.section('General');
}
```
--------------------------------
### ui.createStore(props: Record)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Creates a PetiteVue store for sharing state amongst multiple components.
```APIDOC
## ui.createStore(props)
### Description
Creates a PetiteVue store for sharing state amongst components.
### Parameters
- **props** (Record) - Required - The props that the store should contain.
### Returns
- **ComponentStore** - The PetiteVue store that can be shared between components.
```
--------------------------------
### Get character storage item
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves a previously stored value by its key, returning undefined if the key does not exist.
```javascript
ctx.characterStorage.getItem('coolThings'); // returns ['rocks']
```
--------------------------------
### Execute code on interface ready
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Register a callback to run after offline progress is calculated and the UI is fully initialized.
```javascript
ctx.onInterfaceReady(async (ctx) => {
// ...
});
```
--------------------------------
### Configure and build sidebar categories
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Use category to retrieve or create a category, optionally applying configuration or a builder callback to populate items.
```javascript
// Move COMBAT skills to be below NON-COMBAT
sidebar.category('Combat', { after: 'Non-Combat' });
// Create a new category "GREETINGS" and add an item beneath it
sidebar.category('Greetings', { toggleable: true }, (greetings) => {
greetings.item('Hello');
});
```
--------------------------------
### Execute code on interface available
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Register a callback to run after the game interface is injected but before character loading.
```javascript
ctx.onInterfaceAvailable(async (ctx) => {
// ...
});
```
--------------------------------
### Initialize Patching
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Entry point for creating MethodPatch or PropertyPatch objects for specific classes.
```javascript
ctx.patch(Skill, 'addXP'); // Returns a MethodPatch
ctx.patch(Skill, 'level'); // Returns a PropertyPatch
```
--------------------------------
### loadStylesheet(path: string): void
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Injects a CSS stylesheet into the page.
```APIDOC
## loadStylesheet(path: string): void
### Description
Injects a CSS stylesheet into the page.
### Parameters
- **path** (string) - Required - The relative path to the stylesheet resource.
```
--------------------------------
### settings.section
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Accesses or creates a settings section for the mod.
```APIDOC
## section(name: string)
### Description
Gets or creates a settings section. The order that sections are created determines the display order in the mod's settings window.
### Parameters
- **name** (string) - Required - The name of the section, displayed as a header.
### Returns
- **Section** - The section object used to add, set, or get settings.
### Example
```javascript
ctx.settings.section('General');
```
```
--------------------------------
### loadTemplates(path: string): Promise
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Inject all elements contained in a given HTML file into the document body.
```APIDOC
## loadTemplates(path: string): Promise
### Description
Inject all elements contained in a given HTML file into the document body.
### Parameters
- **path** (string) - Required - The relative path to the HTML resource.
### Returns
- **Promise** - A promise that is resolved once all templates have been injected into the document body.
```
--------------------------------
### Registering Lifecycle Hooks in setup.mjs
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use the mod context object to register callbacks for specific game lifecycle events. These callbacks can be synchronous or asynchronous and receive the mod context as a parameter.
```javascript
// setup.mjs
export function setup({ onModsLoaded, onCharacterLoaded, onInterfaceReady }) {
onModsLoaded(ctx => {
// Utilize other mod APIs at character select
});
onCharacterSelectionLoaded(ctx => {
// Build or modify character selection UI elements
});
onCharacterLoaded(ctx => {
// Modify or hook into game objects to influence offline calculations
});
onInterfaceReady(ctx => {
// Build or modify in-game UI elements
});
}
```
--------------------------------
### Register a Game Data Package
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Registers a game data package from a JSON file path.
```json
// data.json
{
"$schema": "https://melvoridle.com/assets/schema/gameData.json",
"data": {
// data objects here
}
}
```
```javascript
await ctx.gameData.addPackage('data.json');
```
--------------------------------
### loadModule(path: string): Promise
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Dynamically imports a JavaScript module.
```APIDOC
## loadModule(path: string): Promise
### Description
Dynamically imports a JavaScript module.
### Parameters
- **path** (string) - Required - The relative path to the module resource.
### Returns
- **Promise** - A promise that resolves to an object containing all exported features from the module.
```
--------------------------------
### Section.get
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves the current value of a setting.
```APIDOC
## Section.get(name: string)
### Description
Gets the current value of a setting by its name property.
### Parameters
- **name** (string) - Required - The name of the setting.
### Returns
- **any** - The current value of the setting.
### Example
```javascript
ctx.settings.section('Other').get('pick-a-number');
```
```
--------------------------------
### gameData.buildPackage
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Builds a GameDataPackage object using a builder function.
```APIDOC
## buildPackage(builder: (packageBuilder: GameDataPackageBuilder) => void)
### Description
Builds a GameDataPackage object using the GameDataPackageBuilder API.
### Parameters
- **builder** ((packageBuilder: GameDataPackageBuilder) => void) - Required - The builder to be used to add individual game objects to the data package.
### Returns
- **BuiltGameDataPackage** - A wrapper for the game data package.
### Example
```javascript
const pkg = ctx.gameData.buildPackage((p) => { /* ... */ });
pkg.add();
```
```
--------------------------------
### Mount static component
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Use ui.createStatic within the onInterfaceReady hook to mount the template to a specific container.
```javascript
// setup.mjs
export function setup({ onInterfaceReady }) {
onInterfaceReady(() => {
// Create the static component and place it at the bottom of the Woodcutting page
ui.createStatic('#my-static-component', document.getElementById('woodcutting-container'));
});
}
```
--------------------------------
### Define migrated extension manifest.json
Source: https://wiki.melvoridle.com/w/Mod_Creation/Migrating_from_Scripts_and_Extensions
Updated manifest structure using the icon and load properties for the new mod system.
```json
{
"icon": "my-icon-48.png",
"load": ["sources/contentScript.js", "styles/mainStyle.css"]
}
```
--------------------------------
### Loading Packaged Resources
Source: https://wiki.melvoridle.com/w/Mod_Creation/Migrating_from_Scripts_and_Extensions
Retrieving local assets and injecting scripts using the mod context API instead of browser runtime methods.
```javascript
mod.register(async (ctx) => {
var iconUrl = ctx.getResourceUrl('assets/icon.png');
var iconElement = document.createElement('img');
iconElement.src = iconUrl;
await ctx.loadScript('scripts/helper.js');
// Now the contents of helper.js have been injected and executed
});
```
--------------------------------
### Configuring Sidebar Elements
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Pass a configuration object as the second parameter to update properties like positioning or visibility behavior.
```javascript
sidebar.category('Combat').item('Slayer', {
before: 'Attack', // Move the Slayer item above Attack
ignoreToggle: true // Keep Slayer visible when its category has been hidden
});
```
--------------------------------
### Register template in manifest
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Include the HTML file containing templates in the manifest.json load array.
```json
// manifest.json
{
"load": ["static-templates.html"]
}
```
--------------------------------
### gameData.addPackage
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Registers a game data package from a resource path or a JavaScript object.
```APIDOC
## addPackage(data: string | GameDataPackage)
### Description
Registers a game data package. The data can be a resource path to a .json file or a valid JavaScript GameDataPackage object.
### Parameters
- **data** (string | GameDataPackage) - Required - The resource path to your game data package .json file or a valid JavaScript GameDataPackage object.
### Example
```javascript
await ctx.gameData.addPackage('data.json');
```
```
--------------------------------
### Define manifest.json for Userscripts
Source: https://wiki.melvoridle.com/w/Mod_Creation/Migrating_from_Scripts_and_Extensions
Use the load property to point to the script file relative to the manifest.json root.
```json
{
"load": "script.js"
}
```
--------------------------------
### loadScript(path: string): Promise
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Injects a JavaScript file into the page.
```APIDOC
## loadScript(path: string): Promise
### Description
Injects a JavaScript file into the page.
### Parameters
- **path** (string) - Required - The relative path to the script resource.
### Returns
- **Promise** - A promise that resolves when the injected script has finished running.
```
--------------------------------
### Section.add
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Adds a setting or array of settings to a section.
```APIDOC
## Section.add(config: SettingConfig | SettingConfig[])
### Description
Adds a setting to the section. The order of addition determines the display order.
### Parameters
- **config** (SettingConfig | SettingConfig[]) - Required - The setting's configuration object or an array of configuration objects.
### Example
```javascript
ctx.settings.section('General').add({
type: 'switch',
name: 'awesomeness-detection',
label: 'Awesomeness Detection',
default: false
});
```
```
--------------------------------
### Define Text Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for a textbox that accepts string input.
```typescript
interface TextConfig implements SettingConfig {
type: 'text';
maxLength: number; // Max length attribute for the textbox
}
```
--------------------------------
### Implement User Mod Settings
Source: https://wiki.melvoridle.com/w/Mod_Creation/Getting_Started
Define custom settings via the context object to allow players to configure mod behavior dynamically.
```javascript
export function setup(ctx) {
ctx.settings.section('General').add({
type: 'number',
name: 'xp-multiplier',
label: 'XP Multiplier',
hint: 'Multiply all XP gains by this amount',
default: 1
});
ctx.patch(Skill, 'addXP').before(function(amount, masteryAction) {
const xpMultiplier = ctx.settings.section('General').get('xp-multiplier');
return [amount * xpMultiplier, masteryAction];
});
}
```
--------------------------------
### share(resourcePath: string): void
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Shares a packed mod resource so that it can be accessed by other mods using the namespace prefix.
```APIDOC
## share(resourcePath: string)
### Description
Shares a packed mod resource for other mods to use. The resource can be accessed by other mods using the format `namespace:resourcePath`.
### Parameters
- **resourcePath** (string) - Required - The path to the resource to be shared.
### Example
```javascript
ctx.share('my_cool_image.png');
ctx.share('Greeter.mjs');
```
```
--------------------------------
### setItem(key: string, data: any): void
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Sets a key/value pair in account storage. The data must be JSON-serializable.
```APIDOC
## setItem(key: string, data: any): void
### Description
Sets a key/value pair in account storage. Used to persist data associated with a specific key.
### Parameters
- **key** (string) - Required - The key to identify the data being stored.
- **data** (any) - Required - The data to be stored (must be JSON-serializable).
### Example
```javascript
ctx.accountStorage.setItem('coolThings', ['rocks']);
```
```
--------------------------------
### Define Mod Manifest
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
The manifest.json file must be located at the root of the mod directory to define the namespace, icon, and entry points.
```json
{
"namespace": "helloWorld",
"icon": "assets/icon.png",
"setup": "src/setup.mjs",
"load": ["assets/style.css"]
}
```
--------------------------------
### Define Switch Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for an on/off toggle switch.
```typescript
interface SwitchConfig implements SettingConfig {
type: 'switch'
}
```
--------------------------------
### Define Custom Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for a one-off custom-rendered setting.
```typescript
interface CustomConfig implements SettingConfig, SettingTypeConfig {
type: 'custom';
}
```
--------------------------------
### Define Button Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for a clickable button element.
```typescript
interface ButtonConfig implements SettingConfig {
type: 'button';
display: string | HTMLElement; // displayed text or element inside the button
color: string; // see note
onClick(): void; // triggered on click of the button
}
```
--------------------------------
### Define Dropdown Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for a dropdown menu and its associated options.
```typescript
DropdownConfig implements SettingConfig {
type: 'dropdown';
color: string; // see Button config
options: DropdownOption[]; // see note
}
```
```typescript
interface DropdownOption {
value: any; // value that is used by the setting
display: string | HTMLElement; // display text or element on the option
}
```
--------------------------------
### Dynamically load a module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use the loadModule function from the context object to import helper modules relative to the mod root.
```javascript
// setup.mjs
export async function setup({ loadModule }) {
const { greet } = await loadModule('helper.mjs');
greet('Melvor'); // > Hello, Melvor!
}
```
--------------------------------
### Add Settings to a Section
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Add individual or multiple settings to a section using the add method with configuration objects.
```javascript
// setup.mjs
export function setup({ settings }) {
const generalSettings = settings.section('General');
// You can add settings one-by-one
generalSettings.add({
type: 'switch',
name: 'awesomeness-detection',
label: 'Awesomeness Detection',
hint: 'Determines if you are awesome or not.',
default: false
});
// Or multiple at a time by passing in an array
generalSettings.add([{
type: 'label',
display: 'I am just a label though my story seldom told...'
}, {
type: 'number',
name: 'pick-a-number',
label: 'Pick a Number',
hint: '1 through 10'
}]);
}
```
--------------------------------
### Share state between components using a store
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Uses ui.createStore to synchronize state across multiple component instances.
```html
{{ store.count }}
```
```json
// manifest.json
{
"load": ["templates.html"]
}
```
```javascript
// setup.mjs
function CounterUsingStore({ store }) {
return {
$template: '#counter-component-using-store',
store
};
}
export function setup({ onInterfaceReady }) {
onInterfaceReady(() => {
const store = ui.createStore({
count: 0,
inc() {
this.count++;
}
});
// Create and append a CounterUsingStore component to the bottom of the Woodcutting page
ui.create(CounterUsingStore({ store }), document.getElementById('woodcutting-container'));
// Create and append another CounterUsingStore component to the bottom of the Firemaking page
ui.create(CounterUsingStore({ store }), document.getElementById('firemaking-container'));
});
}
```
--------------------------------
### clear(): void
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Removes all key/value pairs from account storage.
```APIDOC
## clear(): void
### Description
Removes all key/value pairs from account storage.
### Example
```javascript
ctx.accountStorage.clear();
```
```
--------------------------------
### Handle Events with v-on
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Bind event listeners using v-on or the @ shorthand to trigger component methods.
```html
```
```html
```
```javascript
function EventBindingExample() {
return {
$template: '#event-binding-template',
onClick() {
alert('You clicked me!');
}
};
}
```
--------------------------------
### Retrieve Resource URL
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Generates a usable URL for a mod-packaged resource. Paths must be relative to the mod root.
```javascript
const url = ctx.getResourceUrl('sea-shanty-2.ogg');
const song = new Audio(url);
song.loop = true;
song.play();
```
--------------------------------
### loadData(path: string): Promise
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Loads data from a JSON resource.
```APIDOC
## loadData(path: string): Promise
### Description
Loads data from a JSON resource.
### Parameters
- **path** (string) - Required - The relative path to the JSON resource.
### Returns
- **Promise** - A promise that resolves to the parsed JSON object.
```
--------------------------------
### Execute code on character selection loaded
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Register a callback to run after the character selection screen has fully loaded.
```javascript
ctx.onCharacterSelectionLoaded(async (ctx) => {
// ...
});
```
--------------------------------
### Define Label Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Configuration for a simple display label.
```typescript
interface LabelConfig implements SettingConfig {
type: 'label';
}
```
--------------------------------
### Define Item Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Interface defining optional properties for sidebar item customization, including styling, icons, and event callbacks.
```typescript
interface ItemConfig {
rootClass?: string | null; // String separated classes to add to the rootEl
itemClass?: string | null; // String separated classes to add to the itemEl
icon?: string | HTMLElement | null; // Either a URL (string) or an HTMLElement to appear in the item's icon slot.
iconClass?: string | null; // String separated classes to add to the iconEl
name?: string | HTMLElement | null; // Override the displayed name (defaults to item id)
nameClass?: string | null; // String separated classes to add to the nameEl
aside?: string | HTMLElement | null; // Text or HTMLElement to be displayed in the aside slot. Example: level (1/99) text on skills.
asideClass?: string | null; // String separated classes to add to the asideEl
link?: string | null; // URL to open if this item is clicked
ignoreToggle?: boolean | null; // Set to true if this item should be visible even if its parent category is hidden. Example: Combat Level under the Combat category.
before?: string; // Places the item before another item by id. Cannot be present if after is defined.
after?: string; // Places the item after another item by id. Cannot be present if before is defined.
onClick?: (() => void) | null; // Code to be executed if the item is clicked
onRender?: (elements: ItemElements) => void; // See notes below
}
```
--------------------------------
### Implement Conditional Rendering
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Use v-if, v-else-if, and v-else to control element visibility based on logic.
```html
FizzBuzzFizzBuzz{{ value }}
```
```javascript
function ConditionalExample(props) {
return {
$template: 'conditional-example',
value: props.value
};
}
ui.create(ConditionalExample({ value: 6 }), host);
// -> Fizz
```
--------------------------------
### getResourceUrl(path: string): string
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves a usable URL for any resource packaged in your mod.
```APIDOC
## getResourceUrl(path: string): string
### Description
Retrieves a usable URL for any resource packaged in your mod.
### Parameters
- **path** (string) - Required - The relative path to the resource to generate a URL for.
### Returns
- **string** - The URL to the requested resource.
```
--------------------------------
### Define Base Setting Configuration
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
The base interface for all individual setting configuration objects.
```typescript
interface SettingConfig {
type: string; // Type of the setting
name: string; // Name of the setting
label: string | HTMLElement; // Display label for the setting
hint: string | HTMLElement; // Small help text to display alongside the setting
default: any; // Default value for the setting
onChange(value: any, previousValue: any): void | boolean | string // See notes
}
```
--------------------------------
### Registering a custom setting type
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Define a new setting type within a mod's namespace and add it to a settings section.
```json
// manifest.json
{
"namespace": "my_mod",
// ...
}
```
```javascript
ctx.settings.type('customText', {
// See example config in SettingTypeConfig section below
});
ctx.settings.section('General').add({
type: 'customText',
// ...
});
```
```javascript
ctx.settings.section('Other').add({
type: 'my_mod:customText',
// ...
});
```
--------------------------------
### Manage Category Items
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Methods for creating, configuring, and nesting items within a category.
```javascript
// Move Astrology above Firemaking
sidebar.category('Non-Combat').item('melvorD:Astrology', { before: 'melvorD:Firemaking' });
// Create a new item and add a subitem beneath it
sidebar.category('General').item('Greetings', { nameClass: 'text-warning' }, (greetings) => {
greetings.subitem('Hello');
});
```
--------------------------------
### MethodPatch.before(hook)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Executes a callback before the original method body runs.
```APIDOC
## MethodPatch.before(hook: (...args: any) => any[] | void)
### Description
Executes a callback function immediately before the method body is called. Optionally returns an array to override arguments.
### Parameters
- **hook** (function) - Required - Callback receiving original arguments. Returns an array of arguments to override or undefined.
```
--------------------------------
### Accessing or Creating Sidebar Elements
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use category, item, and subitem methods to retrieve existing elements or create them if they do not exist.
```javascript
const combat = sidebar.catetory('Combat'); // Get the Combat category, or create one if it doesn't exist
const attack = sidebar.category('Combat').item('Attack'); // Get the Attack item within Combat or create one if it doesn't exist
attack.subitem('Wut'); // Get the Wut subitem within Attack or create one if it doesn't exist
```
--------------------------------
### Lifecycle Hooks
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Methods to register callbacks that execute at various stages of the game and mod loading lifecycle.
```APIDOC
## Lifecycle Hooks
### onModsLoaded(callback)
Executes code after all mods have been loaded.
### onCharacterSelectionLoaded(callback)
Executes code after the character selection screen has fully loaded.
### onInterfaceAvailable(callback)
Executes code after the game interface is injected but before the character is loaded.
### onCharacterLoaded(callback)
Executes code after the character has loaded and game objects are created, but before offline progress.
### onInterfaceReady(callback)
Executes code after offline progress is calculated and the UI is ready.
### Parameters
- **callback** (function) - Required - A function receiving the `ModContext` object, supporting synchronous or asynchronous execution.
```
--------------------------------
### getItem(key: string): any
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Retrieves a value from account storage by its key.
```APIDOC
## getItem(key: string): any
### Description
Gets a value by its key from account storage.
### Parameters
- **key** (string) - Required - The key of the data to retrieve.
### Returns
- **any** - The data retrieved. Returns undefined if no such key is stored.
### Example
```javascript
ctx.accountStorage.getItem('coolThings'); // returns ['rocks']
```
```
--------------------------------
### ctx.settings.type(name, config)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Registers a new setting type that can be used when adding settings to the mod configuration menu.
```APIDOC
## ctx.settings.type(name: string, config: SettingTypeConfig)
### Description
Registers a custom setting type. Once registered, this type can be used in setting configurations. Other mods must prepend the registered name with the mod's namespace (e.g., 'namespace:name').
### Parameters
- **name** (string) - Required - The unique name of the setting type.
- **config** (SettingTypeConfig) - Required - An object defining the behavior of the setting type, including render, get, and set functions.
### SettingTypeConfig
- **render(name: string, onChange: () => void, config: SettingConfig): HTMLElement** - Required - Renders the HTML for the setting.
- **get(root: HTMLElement): any** - Required - Retrieves the current value from the rendered HTML element.
- **set(root: HTMLElement, value: any): void** - Required - Updates the HTML element with a new value.
### Example
```javascript
ctx.settings.type('customText', {
render: (name, onChange, config) => { /* ... */ },
get: (root) => { /* ... */ },
set: (root, value) => { /* ... */ }
});
```
```
--------------------------------
### Dynamically Import Module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Imports a JavaScript module and returns its exports. The module file must use standard ES module export syntax.
```javascript
// my-module.mjs
export function greet(name) {
console.log(`Hello, ${name}!`);
}
```
```javascript
const myModule = await ctx.loadModule('my-module.mjs');
myModule.greet('Melvor'); // Hello, Melvor!
```
--------------------------------
### Execute code on mods loaded
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Register a callback to run after all mods have finished loading.
```javascript
ctx.onModsLoaded(async (ctx) => {
// ...
});
```
--------------------------------
### Item Methods
Source: https://wiki.melvoridle.com/w/Mod_Creation/Sidebar_API_Reference
Methods available on an Item instance to interact with sidebar elements.
```APIDOC
## click()
### Description
Triggers the item's configured `onClick` property, if present.
### Example
```javascript
// Navigate to the Woodcutting page
sidebar.category('Non-Combat').item('melvorD:Woodcutting').click();
```
## toggle(force?: boolean)
### Description
Toggles the visibility of the item's subitem menu, if any subitems exist.
### Parameters
- **force** (boolean) - Optional - Optionally set to `true` to force display the category, `false` to hide.
### Example
```javascript
// Collapse (hide) the Completion Log's submenu if currently expanded (shown)
// Or expand (show) the submenu if currently collapsed (hidden)
sidebar.category('General').item('Completion Log').toggle();
// Collapse (hide) the Completion Log's submenu
sidebar.category('General').item('Completion Log').toggle(false);
```
## remove()
### Description
Removes this item from the parent category.
### Example
```javascript
// Removes the Summoning skill from the sidebar
sidebar.category('Non-Combat').item('melvorD:Summoning').remove();
```
```
--------------------------------
### setItem(key: string, data: any): void
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Sets a key/value pair in character storage. The data must be JSON-serializable.
```APIDOC
## setItem(key: string, data: any): void
### Description
Sets a key/value pair in character storage. Used to save data that persists across sessions for a specific character.
### Parameters
- **key** (string) - The key to identify the data being stored.
- **data** (any) - The JSON-serializable data to be stored.
### Example
```javascript
ctx.characterStorage.setItem('coolThings', ['rocks']);
```
```
--------------------------------
### Bind Attributes with v-bind
Source: https://wiki.melvoridle.com/w/Mod_Creation/Reusable_Components_with_PetiteVue
Use v-bind or the colon shorthand to dynamically set HTML attributes based on component state.
```html
This message could be a warning or informational.
```
```html
This message could be a warning or informational.
```
--------------------------------
### Legacy Loading Loop
Source: https://wiki.melvoridle.com/w/Mod_Creation/Migrating_from_Scripts_and_Extensions
A common pattern used in userscripts to wait for the game to finish loading before executing code.
```javascript
var loadInterval = setInterval(() => {
var isGameLoaded = window.isLoaded && !window.currentlyCatchingUp;
if (isGameLoaded) {
clearInterval(loadInterval);
// Inject script element or execute code...
}
}, 500);
```
--------------------------------
### Registering a Script with Context
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Use mod.register for scripts loaded via manifest or loadScript to receive the context object.
```javascript
mod.register(ctx => {
// ...
});
```
--------------------------------
### Access Developer Context
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Retrieve the development context in the browser console for testing purposes. Do not use this within actual mod code.
```javascript
const devCtx = mod.getDevContext();
```
--------------------------------
### Define mod namespace in manifest
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Specify the mod namespace in the manifest.json file to enable resource sharing.
```json
// manifest.json
{
"namespace": "helloMelvor"
}
```
--------------------------------
### Import a JavaScript module
Source: https://wiki.melvoridle.com/w/Mod_Creation/Essentials
Use loadModule to access exported features from a local JavaScript module.
```javascript
// my-module.mjs
export function greet(name) {
console.log(`Hello, ${name}!`);
}
export const importantData = ['e', 'r', 'e', 'h', 't', ' ', 'o', 'l', 'l', 'e', 'h'];
```
```javascript
// setup.mjs
export async function setup({ loadModule }) {
const myModule = await loadModule('my-module.mjs');
myModule.greet('Melvor'); // Hello, Melvor!
console.log(myModule.importantData.reverse().join('')); // hello there
}
```
--------------------------------
### patch(className: class, methodOrPropertyName: string)
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
The entry-point to the patching API. Returns a MethodPatch or PropertyPatch object based on the target.
```APIDOC
## patch(className: class, methodOrPropertyName: string)
### Description
Initializes a patch for a specific class method or property. Returns a patch object used to define hooks.
### Parameters
- **className** (class) - Required - The class reference containing the target.
- **methodOrPropertyName** (string) - Required - The name of the method or property to patch.
### Returns
- **MethodPatch | PropertyPatch** - A patch object for the specified target.
```
--------------------------------
### Execute code on character loaded
Source: https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference
Register a callback to run after character data is loaded but before offline progress calculations.
```javascript
ctx.onCharacterLoaded(async (ctx) => {
// ...
});
```