Skip to content

File structure and metadata

Structure a BDEngine JS plugin with required name and namespace fields, a version, description, icon, and correctly timed initialization.

UserScript header and code

The file contains metadata comments and executable JavaScript. Save it as a UTF-8 .js file. A plugin is loaded as a regular script, not a JavaScript module: top-level import and export statements are not suitable for this file.

// ==UserScript==
// @name My useful plugin
// @namespace my-useful-plugin
// @version 1.0.0
// @description Adds a useful tool to BDEngine.
// @author Your name
// @logo_url https://editor.bdecdn.com/icon/icon-192x192.png
// ==/UserScript==
(() => {
console.log('[my-useful-plugin] Script loaded');
})();

The ==UserScript== markers make the file easier to read. The loader itself looks for tagged lines in comments; it does not support every feature of UserScript managers. For example, @require, @grant, and @match do not load dependencies or configure plugin permissions in BDEngine.

Write each tag on its own line without indentation before //. The loader can also read tags from a block comment. Avoid repeating a tag in multiple places: keep one clear header at the start of the file.

Required name and namespace

Field Purpose
@name A human-readable name for the installed plugins list.
@namespace The persistent identifier of the installed plugin. It is used to store the code and determine replacements.

A local file cannot be installed if either field is empty or missing. The filename does not replace @namespace: tool.js and new-tool.js with the same namespace are treated as one plugin. Installing through My plugins replaces the saved entry with that identifier. Changes take effect after restarting the editor.

Choose a namespace that does not conflict with another plugin and keep it across updates. If you plan to publish, it is convenient to use the intended catalog slug from the beginning, such as my-useful-plugin. This is a consistency recommendation, not an additional namespace format check in the local loader.

description, logo_url, author, version

Field Purpose If omitted
@description A short description in the plugin manager. -
@logo_url The URL of the icon image. The default BDEngine icon.
@author The author’s name or nickname. Author
@version The version shown for the installed plugin. 1.0.0

The icon field is specifically @logo_url. The loader does not use @icon_url. Update the version in the header along with your code. The local loader reads it as a string; the requirement for three numeric parts applies to the catalog’s publication form.

Entry point and global scope

The file runs during editor startup, before the GUI is ready. window.editorAPI already exists at that point, but windows and Dock buttons should be added after bde:started:

(() => {
const log = (...args) => console.log('[my-useful-plugin]', ...args);
window.addEventListener('bde:started', () => {
log('Editor UI is ready');
// You can create the interface through window.editorAPI here.
}, { once: true });
})();

An IIFE provides a private scope for variables and functions. It is a convenient way to avoid conflicts with other plugins, not a required execution format. The loader does not automatically call functions named init or unload.

Normal installation saves the file and offers a restart. When running code manually in an already open editor, bde:started may have fired already: a new listener will not receive that past event. For debugging, call your initialization function explicitly once the editor is ready. See events and lifecycle.

Updates and publishing

A plugin namespace, catalog page slug, project ID, and Minecraft tags serve different purposes. For local installation, metadata comes from the JS header. For catalog installation, the editor receives metadata from the catalog and uses its slug as the namespace, along with the name, description, author, version, and icon from the response.

If a local copy has a different namespace, installing from the catalog creates a separate entry. Both copies may run after restarting. Before testing the published version, remove the old test copy or align the namespace with the slug in advance.

For creating a listing, moderation, and updates, see Publishing and versions.