Documentation for JS plugins for BDEngine

This section is currently being written and will be updated frequently.

Important: only the API from window.editorAPI is considered stable and officially supported.

The window.editor object is available for exploration and experimentation, but its structure may change without notice and compatibility between versions is not guaranteed.

Functions of the Official API

Desc
Creating a window

Creates a custom window inside the editor where the plugin can display any custom HTML content.

Deleted after closing.

Signature

editorAPI.createWindow(
    name = 'Window',
    name_id = 'default',
    icon = 'icon-layout-grid',
    width = 1100,
    height = 550,
    minWidth = 500,
    minHeight = 400,
    closeFunc = () => {}
);

Example of use:

// ==UserScript==
// @name         Example window
// @namespace    example-window
// @description  Demonstration editorAPI.createWindow
// ==/UserScript==

(() => {
    const log = (...args) => console.log('[Example Window]', ...args);

    const win = editorAPI.createWindow(
        'My window',
        'my-window',
        'icon-anchor',
        800,
        500,
        400,
        300,
        () => log('The window is closed')
    );

    win.container.innerHTML = `Hello World!`;

})();
Creating a modal window

Creates a modal window inside the scene window, in which the plugin can display any user-defined HTML content.

Not deleted after closing (hiding).

Signature

editorAPI.createModalWindow(name = 'Window');

Example of use:

// ==UserScript==
// @name         Example modal window
// @namespace    example-modal-window
// @description  Demonstration editorAPI.createModalWindow
// ==/UserScript==

(() => {
    const log = (...args) => console.log('[Example Window]', ...args);

    const win = editorAPI.createModalWindow('My window');

    win.container.innerHTML = 'Hello World!';

    win.showModal();

    // win.hideModal(); - To hide the window

})();
Project insertion

Inserts a JSON project in BDEngine format into the currently open project. Both base64+gzip encrypted and plain JSON.

Signature

await editorAPI.mergeContent(content, decode = false);
Adding built-in editor objects

Creates and adds a built-in editor object such as BlockDisplay, ItemDisplay or TextDisplay.

If parent is passed, the object is added directly into that parent.

Signature

await editorAPI.add(
    identifier,
    type,
    parent = null,
    save = true,
    objPos,
    noReply = false
);

Example:

const text = await editorAPI.add('Hello', 'TextDisplay');
const item = await editorAPI.add('player_head', 'ItemDisplay');
const block = await editorAPI.add('stone', 'BlockDisplay');
Adding custom plugin objects

Adds your own already-created object into the editor scene.

Use this for custom plugin objects, for example classes based on Selectable.

Signature

editorAPI.addObject(object, parent = null);

Example:

class ExampleSelectable extends Selectable {
    constructor(editor) {
        super(editor);
    }
}

const obj = new ExampleSelectable(editor);
editorAPI.addObject(obj);
Adding a button to the dock menu

Adds a button to the main dock menu of the editor.

Signature

editorAPI.addButtonDockMenu(
    icon = 'icon-box',
    name = 'New button',
    func = () => {},
    sound = true
);
Adding a tool button

Adds a button to the left or right tool strip.

Signature

editorAPI.addButtonTool(
    icon,
    func,
    right = false,
    sound = true
);
Finding editor objects

Searches objects inside the editor by property and value.

Signature

editorAPI.find(key, val = true);
Getting selected objects

Returns an array of objects that are currently selected in the editor.

Signature

editorAPI.getSelectedObjects();

Example:

const selected = editorAPI.getSelectedObjects();

if (selected.length > 0) {
    console.log('Selected objects:', selected);
    console.log('First selected object:', selected[0]);
}
Getting meshes

Returns an array of temporary THREE.Mesh objects built from the current editor scene.

Instanced displays are expanded into regular THREE.Mesh objects.

The returned array does not include editor helpers, gizmos, or RT lights.

Signature

editorAPI.getMeshes();

Example:

const meshes = editorAPI.getMeshes();
console.log('Meshes:', meshes.length);
console.log('First mesh:', meshes[0] || null);
Deleting objects

Deletes the specified objects through the editor workflow.

This is the preferred way to remove objects because it goes through the editor deletion logic.

Signature

editorAPI.delete(objects);
Deleting selected objects

Deletes the objects that are currently selected in the editor.

Signature

editorAPI.deleteSelected();
Removing one object

A convenience wrapper for removing a single object.

Signature

editorAPI.removeObject(object);
Updating the editor

Forces the editor to update its state and optionally refresh transform controls.

Signature

editorAPI.update(withControl = false);
Plugin translations

Plugins can register their own translation keys and then use them through gT(...).

When you call editorAPI.registerTranslations(namespace, ...), simple keys are automatically prefixed with the plugin namespace.

For example, the key button registered under the namespace my-plugin becomes my-plugin.button.

Signature

editorAPI.registerTranslations(namespace, translations = {});

Example:

// ==UserScript==
// @name         Example translations
// @namespace    example-translations
// @description  Demonstration of plugin translations
// ==/UserScript==

(() => {
    editorAPI.registerTranslations('example-translations', {
        en: {
            button: 'Open example window'
        },
        ru: {
            button: 'Открыть окно примера'
        }
    });

    editorAPI.addButtonDockMenu(
        'icon-box',
        gT('example-translations.button', 'Open example window'),
        () => {
            const win = editorAPI.createWindow('Example', 'example-window');
            win.container.innerHTML = '<div>Hello!</div>';
        }
    );
})();

Recommended usage: register simple keys like button, then read them through gT('your-namespace.button', fallback).

Simple keys are automatically prefixed with the plugin namespace. If needed, you can still pass a fully qualified key explicitly.

Sign up to create and share content. Sign up
Dashboard
Chats
Sign In
Browse