Rune Docs

Plugin Structure

Introduction

Creating a plugin requires the following minimum requirements:

  • main.lua - Your entrypoint, the script that executes when enabling the plugin.
  • plugin.json - Manifest for the plugin.
  • resources/ - optional resources folder containing additional resources required for the plugin.

Plugin Paths

These are the only hardcoded paths used by the plugin system. Plugins may contain additional Lua files and folders beyond what the minimum requirements are for your plugin to function.

Plugin Resources

See the dedicated resources page for more information on working and managing resources.

Permissions

Plugins carry a vast variety of configurable options, some of which can present a risk for a user. The plugin system allows for permission-restricted functionality to work around this, which you can configure via the manifest.

Plugin Permissions

These permissions can be either required for a plugin to function or optional allowing extended functionality of a user accepts those permissions.

See the plugin page for a list of available permissions and this page on checking optional permissions.

Manifest

Your plugin.json manifest file defines user-friendly information for plugins including potential dependencies and permissions.

FieldTypeDescription
nameStringYour user-friendly name for the plugin.
versionStringYour user-friendly version for the plugin. Typically the version displayed when downloading it.
contactEmailAddressStringA contact email address for the plugin author.
requiredDependencies[String] or { String -> String }Specifies the list of dependencies this plugin depends on.
optionalDependencies[String] or { String -> String }Specifies the list of dependencies this plugin optionally depends on.
requiredPermissions[String]A list of permissions required for this plugin to function.
optionalPermissions[String]A list of permissions that strictly provide added functionality for this plugin rather than being required for it to function.
urls{ String -> String }Specifies the base URLs that may be used by this plugin, with the mapping representing Var Name -> URL.

Plugin URLs

These must represent HTTP or HTTPS URLs.

Example Manifest

plugin.json
{
    "name": "My Awesome Plugin",
    "version": "1.0.0",
    "contactEmailAddress": "example.email@website.com",
    "requiredDependencies": [],
    "optionalDependencies": [],
    "requiredPermissions": [ "httpAccess" ],
    "optionalPermissions": [],
    "urls": { "jagex" : "http://www.jagex.com", "rswiki" : "https://runescape.wiki/" },
}

Additional Manifest Info

Your manifest may also contain additional fields for plugins retrieved from remote repositories and are usually prefixed with the word remote.

Dependencies

Plugins can require other plugins as dependencies and or utilize multiple Lua files instead of putting everything in a singular main.lua file.

To achieve this, you need to utilize the require function with the path of the file you wish to load, omitting its file extension. This will then return the result of executing that file or nil if the execution file(s) do not exist.

Cylical Dependencies

Cylical dependencies are prohibited. If two or more dependencies form a cycle (e.g., A depends on B, and B depends on A), an error will occur.

Require Path

The path passed to require must be relative to the plugin's root folder.

Require Execution

require only executes the specified script once, returning a cached result in subsequent calls for the same script.

External Dependencies

Implementing additional libraries can help extend the functionality of your plugins without requiring you to embed them within your own plugin.

Dependencies between plugins are straight forward, requiring only a change to your manifest.json file to include the folder name of the plugin you wish to depend on.

You can define both requiredDependencies and optionalDependencies within your manifest.json depending on the scope and functionality desired for your plugin.

MyAwesomePlugin/plugin.json
"requiredDependencies": [ "MyAmazingPlugin" ],
"optionalDependencies": [ "MyCoolOptionalPlugin" ],

These dependencies are then loaded before the current plugin, and its results are cloned exposing them within your own plugin as a variable.

Plugin Naming Conflict

In case the plugin's name can't be used directly as an identifier in Lua, it will be prefixed or replaced with a _ (eg. 2!GraphLib becomes _2_GraphLib). An alternative is to explicitly alias it when defining dependencies, like so:

MyAwesomePlugin/plugin.json
"requiredDependencies": { "OtherPlugin" : "MyAmazingPlugin" },
"optionalDependencies": { "OptPlugin" : "MyCoolOptionalPlugin" },

Warning

Since exported tables are shared across any number of imports, if you need to provide per-plugin functionality in a library plugin, consider exporting instead functionality to create a stateful object which importers can pass in calls to your library, or which wraps the calls entirely.

Similarly, importing plugins must not modify the contents of imports, as that would also affect other plugins.

Dependency Updates

Whether or not optional dependencies are enabled can change while a plugin is running, plugins can define a PluginDependencyUpdate function in global scope which will then be called whenever the state of an optional dependency defined in plugin.json changes.

This method is automatically converted into an OptionalDependencyChanged event.

function PluginDependencyUpdate(optionalDependencyChangedEvent)

The payload values of optionalDependencyChangedEvent are listed below.

FieldTypeDescription
pluginIdentifierStringThe identifier that would be used to access that dependency's data were it available.
enabledBoolWhether or not the dependency is enabled currently.

local enableAdditionalFeatures = false

function PluginDependencyUpdate(info)
    print("Optional dependency", info.pluginIdentifier, "is now", info.enabled)

    if info.pluginIdentifier == "OptPlugin" then
        enableAdditionalFeatures = info.enabled
    end
end```

Built by Astrect and contributors. These are community-sourced docs intended to supplement the official documentation, that can be found at https://developer.runescape.com/rs/index.html.

On this page