# Melonjs Plugins

Use this skill when adding a melonJS plugin or adapter, the debug panel, Spine...

- Repository: https://github.com/melonjs/melonJS (6430 stars)
- Category: Design
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add melonjs/melonJS --skill melonjs-plugins -g -a claude-code -y`
Codex: `npx skills add melonjs/melonJS --skill melonjs-plugins -g -a codex -y`
Cursor: `npx skills add melonjs/melonJS --skill melonjs-plugins -g -a cursor -y`
Gemini CLI: `npx skills add melonjs/melonJS --skill melonjs-plugins -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add melonjs/melonJS`

## Description

Use this skill when adding a melonJS plugin or adapter, the debug panel, Spine skeletal animation, compressed Tiled map support, on-screen touch controls, Capacitor packaging, or when writing your own plugin. Covers plugin.register and its version gate, plugin.cache, plugin.patch, and why physics adapters are not plugins. Triggers on: plugin, plugin.register, plugin.cache, plugin.get, plugin.patch, BasePlugin, debug-plugin, DebugPanelPlugin, SpinePlugin, TiledInflatePlugin, GamepadPlugin, gamepad-plugin, touch controls, virtual joystick, CapacitorPlugin, adapter, custom plugin, plugin version mismatch, already registered.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Plugins and adapters

## Two different mechanisms

This trips people up, so it is worth stating first:

| | how it is installed |
|---|---|
| **Plugins** | `plugin.register(Class, name?, ...args)`, after `await app.init()` |
| **Physics adapters** | an `Application` **setting** (`physic:`), before `init()` |

```js
// the adapter is chosen at construction …
const app = new Application(800, 600, {
    parent: "screen",
    physic: new PlanckAdapter({ gravity, pixelsPerMeter }),
});

// … the plugin is registered once the renderer exists
await app.init();
plugin.register(DebugPanelPlugin, "debugPanel");
```

## `register` in detail

```js
plugin.register(PluginClass, "name", ...constructorArgs);
plugin.cache.name;              // the instance
plugin.get(PluginClass);        // by class, or by registered name string
```

- **The name is optional**, it falls back to the class name.
- **The registry is global, not per-application.** It is a module-level object,
  so registering the same name twice throws `plugin <name> already registered`.
  A plugin *instance* does hold an `app` reference, but it defaults to `game`, **whichever Application most recently finished `init()`**, since that is where
  `game` is assigned. On a multi-application page, pass the app explicitly
  through the constructor args:
  `plugin.register(DebugPanelPlugin, "debugPanel", input.KEY.S, myApp)`.
- **`BasePlugin.version` is a floor, not an identity.** It declares the
  *minimum melonJS version the plugin needs*, and `register` throws
  `Plugin version mismatch, expected: <floor>, got: <engine>` when the running
  engine is older. That gate is the real enforcement, a peer-dependency range
  only warns at install time, and not at all for CDN or pre-bundled use. If you
  see that error, upgrade the engine or pin an older plugin. The check runs
  *after* the instance is constructed, so a plugin whose constructor has side
  effects will already have run them when it throws.

The rest: https://github.com/melonjs/melonJS/blob/HEAD/packages/melonjs/skills/melonjs-plugins/SKILL.md
