Skip to content

phaserjs/phaser-editor-5-plugin-template

Repository files navigation

Phaser Editor v5 — Plugin Template

A minimal, self-contained template for building third-party plugins for Phaser Editor v5.

This template ships one example plugin (myplugin.example) that contributes a custom command to the editor. Use it as the starting point for your own plugin: clone it, rename it, and grow it.


Developing with AI assistance

This template is set up so an AI coding assistant can help you build plugin features effectively:

The bundled types/*.d.ts give the AI the editor's real API surface, and myplugin.example is a complete worked example to copy from. Just ask your assistant something like "add a command that …" or "add an editor for .foo files" and it will follow these docs.


How a plugin works

A Phaser Editor plugin is just a folder containing:

  • a plugin.json manifest, and
  • one or more JavaScript files (and optional CSS) listed in that manifest.

Loading happens in two steps:

  1. Discovery (server side). When the editor starts, the server scans its plugin directories. For every folder that has a plugin.json, it injects the listed scripts and styles into the editor page.
  2. Registration (client side). When your script runs in the page, it calls colibri.Platform.addPlugin(...) to register your plugin instance. During startup the editor then calls your plugin's registerExtensions(reg) method, where you contribute commands, menus, editors, views, and so on.

There is no webpack or runtime npm dependency. The build is plain TypeScript: each plugin compiles to a single concatenated file (_out/<id>.js) via tsc with outFile.

This template compiles against a bundled snapshot of the editor's API types (types/colibri.d.ts), so you do not need a checkout of the editor source to build your plugin.


Project structure

phaser-editor-5-plugin-template/
├── README.md                # this file
├── AGENTS.md                # AI-agent entry point (architecture + conventions)
├── docs/                    # developer recipes (commands, editors, styles, ...)
├── .cursor/skills/          # Cursor skill for plugin development
├── package.json             # build scripts + the typescript devDependency
├── update-types.mjs         # copies all editor plugin .d.ts into types/
├── tsconfig.json            # solution file: references the example plugin's src
├── tsconfig-base.json       # shared compiler options
├── types/                   # bundled API snapshots, one .d.ts per editor plugin
│   ├── colibri.d.ts             # core editor API
│   ├── phasereditor2d.files.d.ts # the New File wizard (Files plugin)
│   ├── phasereditor2d.phaser.d.ts # Phaser + scene types
│   └── ...                       # every other editor plugin
└── myplugin.example/        # the example plugin (folder name == plugin id)
    ├── plugin.json          # manifest: id + scripts + styles
    ├── styles/
    │   └── TodoEditor.css   # theme-scoped styles for the Todo editor
    ├── _out/                # build output (generated; git-ignored)
    │   └── myplugin.example.js
    └── src/
        ├── tsconfig.json    # outFile -> ../_out/myplugin.example.js
        ├── ExamplePlugin.ts # plugin class: registers the command, content type, editor
        └── editors/         # the custom "Todo" editor example
            ├── TodoModel.ts                     # data model + ".todo" content type id
            ├── TodoEditor.ts                    # the editor, viewer, commands, toolbar
            ├── TodoEditorOutlineProvider.ts     # feeds the Outline view
            ├── TodoEditorProperties.ts          # Inspector sections (name/description/state)
            └── NewTodoFileExtension.ts          # "New Todo File" wizard entry

Prerequisites

  • Node.js (any recent LTS) and npm.
  • An installed copy of Phaser Editor v5 (desktop or the CLI launcher).

Build

npm install
npm run build

This produces myplugin.example/_out/myplugin.example.js.

Other scripts:

  • npm run watch — rebuild on every change (great while developing).
  • npm run clean — remove the build output.

Install / test the plugin

After building, make the editor aware of the plugin in any one of these ways:

Option A — User plugins folder

Copy the plugin folder into your user plugins directory:

cp -r myplugin.example ~/.phasereditor2d/plugins/

Restart the editor. The plugin loads automatically.

Option B — -plugins launcher flag (best for development)

Point the launcher at this template's root directory. The editor scans each subfolder for a plugin.json; types/ is ignored because it has none:

PhaserEditor -plugins /path/to/phaser-editor-5-plugin-template

Combine with npm run watch to iterate quickly — rebuild, then reload the editor page.

Option C — Per-project config

In a game project, add the plugin's path to phasereditor2d.config.json:

{
    "plugins": ["/path/to/phaser-editor-5-plugin-template/myplugin.example"]
}

Running the command

Once loaded, run the example command in either way:

  • Open the command palette with Ctrl+K, search for "Hello From Plugin".
  • Or press the shortcut Ctrl+Alt+H.

You should see a "Hello from myplugin.example!" message.


Renaming / cloning the plugin

To turn this into your own plugin, change the id everywhere so the manifest, the compiled file, the namespace, and the build reference all stay in sync:

  1. Rename the folder myplugin.example/ to your plugin id, e.g. com.acme.tools.
  2. In com.acme.tools/plugin.json: set "id" and the script path in "scripts".
  3. In com.acme.tools/src/tsconfig.json: update outFile to ../_out/com.acme.tools.js.
  4. In com.acme.tools/src/ExamplePlugin.ts: rename the namespace, the super("...") id, and the command/category ids.
  5. In the root tsconfig.json: update the references path.

Use a unique, namespaced id (reverse-domain style is a good convention) to avoid clashing with other plugins. Command ids follow the convention <pluginId>.<ActionName>.


Adding more commands

Add more manager.add({ ... }) calls inside the CommandExtension in ExamplePlugin.ts. Each command takes:

  • command: metadata (id, name, tooltip, category).
  • handler: behavior — executeFunc(args) runs the command, and an optional testFunc(args) controls when it is enabled (e.g. only in a specific editor).
  • keys: an optional keyboard shortcut (control / shift / alt / meta flags plus a key).

The args passed to the handlers give you the active part, editor, selection, and window — see colibri.ui.ide.commands in types/colibri.d.ts.

Other extension points

Commands are just one extension point. Browse types/colibri.d.ts for more, including:

  • colibri.ui.controls.menus (MenuExtension) — contribute menu entries that reference your command ids.
  • colibri.ui.ide.EditorExtension / WindowExtension — custom editors and views.
  • colibri.core.ContentTypeExtension / colibri.core.io.FileStorageExtension — content types and file storage.

All of them are contributed the same way: reg.addExtension(new ...Extension(...)) inside registerExtensions.


Custom editor example: the Todo editor

The template also ships a small but complete custom editor that opens .todo files. It is a rich HTML-based editor (it builds its own DOM instead of using a tree viewer), and it demonstrates the most common building blocks of a Phaser Editor editor: a content type, the Outline view, the Inspector (properties) view, and theme-correct CSS, with selection kept in sync between all three.

Try it

  1. Build the plugin and make the editor aware of it (see the sections above).

  2. Create a new todo file with the New File wizard, in any of these ways:

    • Right-click a folder in the Files view -> New... -> Todo File, or
    • press Ctrl+Alt+N and pick Todo File, or
    • use the New File button in the main toolbar.

    A tasks.todo file is created (pre-filled with one example task) and opens automatically in the Todo Editor, which pretty-prints each task (name + colored state).

  3. Use the editor toolbar (or right-click for the context menu) to Add Task, Delete, Move Up, and Move Down. Pressing A adds a task; Delete removes the selected ones.

  4. Open the Outline view to see every task listed by name.

  5. Open the Inspector view and select a task (in the editor or the outline) to edit its name, state, and description. Changes are reflected immediately and mark the editor dirty (save with Ctrl+S).

How it is wired

flowchart LR
    file[".todo file"] --> ct["Content type<br/>ContentTypeResolverByExtension"]
    ct --> factory["ContentTypeEditorFactory"]
    factory --> editor["TodoEditor<br/>(FileEditor + HTML task cards)"]
    editor -->|"getEditorViewerProvider('Outline')"| outline["TodoEditorOutlineProvider<br/>-> Outline view"]
    editor -->|"getPropertyProvider()"| props["TodoEditorPropertySectionProvider<br/>-> Inspector view"]
    editor -->|selection| outline
    outline -->|onViewerSelectionChanged| editor
    editor -->|selection| props
Loading
  • Content type (TodoModel.ts): colibri.core.ContentTypeResolverByExtension maps the todo extension to the content type id CONTENT_TYPE_TODO. The data model (TodoModel / TodoTask) serializes to/from JSON.
  • Editor (TodoEditor.ts): extends colibri.ui.ide.FileEditor and builds its own HTML in createPart - a scrollable list of task "cards" (name + colored state badge + description). It tracks its own selection (_selectedTasks), highlights the selected cards, supports Ctrl/Cmd-click for multi-select, loads the file in createPart, saves JSON in doSave, and exposes Add / Delete / Move Up / Move Down commands via a toolbar and context menu.
  • Styles (TodoEditor.css): theme-correct CSS registered in plugin.json. Layout is theme-agnostic; colors are scoped per theme class, grouped for the dark-like themes (dark, phaserstudio) and the light-like themes (light, lightBlue, lightGray).
  • Outline (TodoEditorOutlineProvider.ts): an EditorViewerProvider returned for the "Outline" key. It lists tasks by name and pushes outline selection back into the editor.
  • Inspector (TodoEditorProperties.ts): a PropertySectionProvider with a single PropertySection that renders the name (text), state (menu button), and description (text area). It is returned by both the editor (getPropertyProvider) and the outline provider (getPropertySectionProvider), so it works whichever view has focus.
  • New File wizard (NewTodoFileExtension.ts): extends phasereditor2d.files.ui.dialogs.NewFileContentExtension so a Todo File entry appears in the New File wizard (Ctrl+Alt+N), the Files view New... menu, and the New File toolbar button. It generates the initial JSON content and the editor opens the file automatically. This is the same mechanism used by the built-in Scene File and Asset Pack File wizards.

Selection routing: when you click a card, the editor calls setSelection(tasks) on its Part, which the Inspector view listens to, and it mirrors the selection to the outline provider. When you click in the Outline, the provider's onViewerSelectionChanged pushes the selection back into the editor (which then updates the inspector). A syncOutline flag prevents feedback loops.

Note on bundled types: the editor compiles against colibri.d.ts, and it returns the outline provider by comparing the key against the literal "Outline" (the value of OutlineView.EDITOR_VIEWER_PROVIDER_KEY) so it needs no outline/inspector types. The only feature that needs a second declaration file is the New File wizard, because its base class lives in the Files plugin — hence the bundled phasereditor2d.files.d.ts.


Updating the types

The files in types/ are snapshots of the editor API (one .d.ts per editor plugin), so this template compiles against the full editor API without an editor checkout. They are taken from a specific editor version.

To refresh them from your editor source, set PHASEREDITOR5_HOME to the folder that contains phaser-editor-v5 and run the bundled script:

export PHASEREDITOR5_HOME=/path/to/parent   # so the source is at
                                            # $PHASEREDITOR5_HOME/phaser-editor-v5/workbench
npm run update-types

The script copies every <plugin>/_out/<plugin>.d.ts from $PHASEREDITOR5_HOME/phaser-editor-v5/workbench/source/editor/plugins into types/. The editor must have been built (its _out folders must exist).

Because types/*.d.ts are all included by myplugin.example/src/tsconfig.json, every plugin's API is available to your code immediately after running the script.

About

A template for creating third-party plugins for Phaser Editor v5.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors