What a plugin is
A plugin is a mod with two extra things in its folder:- a
reskate-plugin.jsonbeside the mod’smanifest.json, which makes the mod a plugin (see the manifest), and - Luau scripts, starting with the entry file the manifest names, such as
plugin/main.lua.
reskate table, and every call into it checks its arguments and its permission before anything happens.
What a plugin can do
What a plugin may touch depends on the permissions its manifest lists. With none, it gets the base set: logging, events such astick and level_loaded, timers, its own files, JSON, and functions and events shared with other plugins. Each permission then unlocks one area, for example:
- reading the skater, its tricks, its bails and its physics steps (
skater.read,events.tricks,events.skater,events.physics), - drawing on the screen and in the world, a page of its own in the menu, and full-screen screens (
overlay,menu,ui.screen), - moving the skater, the camera and the board, and playing animation clips (
skater.teleport,skater.control,camera,board,skater.animation), - talking to the same plugin on other players’ games, and web requests to hosts it names (
net.session,net.http), - running a session as its authority: kicking, announcing and moving players (
server).
What a plugin can never do
Some things are left out of the API on purpose, whatever a manifest asks for:- Write cosmetics, entitlements or progression.
progression.readandsettings.readonly read.outfitwears tattoos, moles and eyewear over your outfit, and never a paid store item. - Run ReSkate’s console commands. A plugin adds its own commands. ReSkate refuses a command name whose first word is one of ReSkate’s,
pluginorhelp. - Reach game memory, files or programs. There is no API for memory, no
io, noos.execute, and no loading of code but the plugin’s own Luau source. A plugin reads only files inside its own package. - Use the microphone, voice audio or the clipboard.
voice.controlsets how loud another player is to you, nothing more.
How ReSkate finds plugins
ReSkate looks through theMods folder beside the game every 2 seconds. A mod is a plugin when:
- it is switched on (
mods.jsondoes not list it as off; a foldermods.jsondoes not list is on), and - it has a
reskate-plugin.jsonat the top of its folder.
Hot reload
ReSkate notices when any file of a plugin’s folder changes (a name, a size or a write time). The plugin then unloads (itsunload handlers run) and loads again from its files. Its storage is saved before it unloads and read back when it loads. The log says:
plugin off stays off when its files change.
Packages that are refused
A plugin never ships a program. ReSkate refuses to load a plugin whose folder holds:- a Windows executable, found by its first bytes (
MZ) whatever its name, or - a file with one of these extensions:
.exe,.dll,.sys,.scr,.com,.cpl,.msi,.msp,.bat,.cmd,.ps1,.psm1,.vbs,.vbe,.js,.jse,.wsf,.wsh,.hta,.lnk,.pifor.reg, or - more than 20000 files.
.js is on the list: a plugin cannot ship JavaScript files, even ones it never runs.The plugin console commands
Open ReSkate’s console to see and control plugins. <id> is the plugin’s mod folder name, or <folder>@server for a server copy while this game hosts a lobby.
plugin list prints one line a plugin:
plugin reload and plugin on answer Plugin <id> reloaded. or Plugin <id> started. when it runs, and error: Plugin <id> did not start: <why> when it does not. For a server copy the answer names its folder, without @server.
In the game,
plugin reload, plugin off and plugin on act on a plugin’s client copy, and on its server copy when you add @server to its id: plugin reload referee@server. Server copies run only while this game hosts a lobby; at other times <folder>@server answers error: server copies run only while this game hosts a lobby. A dedicated server’s console has the same plugin commands for its own plugins, with no @server.Client and server copies
A plugin can run in two places:- The client copy runs on a player’s game. It draws, reads the local skater and plays sounds.
- The server copy is the session’s authority. It runs on the game of a lobby’s host (while that game hosts a lobby that is not on a dedicated server) and on a dedicated server, which loads plugins from a
Pluginsfolder beside it. A server copy draws nothing.
side picks where a plugin runs: "client" (the default), "server" or "both". A "both" plugin on a lobby’s host runs twice there, as two separate VMs.
On a lobby’s host, the server copy has an id of its own, <folder>@server, and reskate.id says so. Everything it holds in the game goes under that id, as do its log lines ([<folder>@server] ...), its storage and its console commands. The two copies share nothing in the game: when the server copy stops, or the game stops hosting, the client copy keeps its camera, its sounds, its outfit items, its board changes and the rest. On a dedicated server, the server copy’s id is its folder name, with no @server.
Your code tells the copies apart with reskate.side: "server" in the server copy, "client" in the client copy.
server functions (kick, announce, tell, move a player). Client copies talk to it with reskate.net.send("server", ...), and it answers to "all" or to one player. The same plugin on every game shares one message channel: the name in its manifest.json.
Where to go next
Quickstart
Make a first plugin with a console command and a speed readout.
Manifest
Every field of
reskate-plugin.json, and the rules it is checked against.Permissions
All 42 permissions: what each unlocks and what other players see.
Limits
The sandbox, every limit, and what happens when a plugin goes over one.
Events
The 24 events, when they fire and what they hand your handler.
Base API
reskate.id, reskate.side, reskate.log, reskate.on and require.