Создание модуля

Структура модуля, точка входа, жизненный цикл и первый рабочий пример.

Структура модуля

Модули находятся в папке mods в корне Toolbox. Обычный модуль — отдельная папка. Старый standalone-формат состоит из одного .js и имеет ограниченные возможности; для новой разработки используйте папку с module.json.

mods/
    hello-toolbox/
        module.json
        index.js

Toolbox загружает точку входа через require(папкаМодуля): обычно это index.js; поле main в package.json позволяет указать другой файл. Метаданные Toolbox лежат в module.json, а не в package.json. Для обновляемого модуля также нужен manifest.json.

Первый модуль

Создайте module.json:

{
    "name": "hello-toolbox",
    "author": "Your name",
    "description": "A minimal Toolbox module",
    "disableAutoUpdate": true
}

Создайте index.js:

module.exports = function HelloToolbox(mod) {
    const onEnter = () => mod.log(`Hello, ${mod.game.me.name}!`);
    mod.game.on('enter_game', onEnter);
    mod.command.add('hello', () => mod.command.message('Hello from Toolbox!'));

    this.destructor = () => {
        mod.game.removeListener('enter_game', onEnter);
    };
};

Перезапустите Toolbox и подключитесь к серверу через него. При входе персонажа появится сообщение в логе; команда hello отвечает в игре через модуль command. Во время разработки отключенное автообновление защищает локальные изменения от замены серверной копией.

Экспорт и жизненный цикл

Класс также может быть точкой входа:

module.exports.NetworkMod = class Example {
    constructor(mod) {
        this.mod = mod;
        mod.log('Module loaded');
    }

    destructor() {
        this.mod.log('Module unloaded');
    }
};
Экспорт Область жизни
GlobalMod Один экземпляр загруженного модуля
ClientMod Экземпляр на подключенный клиентский интерфейс
NetworkMod Экземпляр на сетевое подключение к игре
RequireInterface Представление модуля для зависимых модулей

Обычный экспорт функции или класса поддерживается оберткой совместимости. Явные именованные экспорты позволяют разделить клиентскую, сетевую и общую логику. Не храните состояние разных игровых подключений в общей переменной уровня файла, если оно должно быть независимым.

Toolbox вызывает необязательный destructor() при выгрузке экземпляра. Хуки, команды и управляемые таймеры очищаются инфраструктурой; свои слушатели событий на общих объектах, окна и прочие ресурсы освобождайте самостоятельно. Конструктор не должен быть async: асинхронную работу запускайте из подходящего события, обрабатывая ошибки.

Следующие шаги

Читайте метаданные и обновления, хуки и состояние игры. Сетевой модуль обрабатывает пакеты, а клиентский может устанавливать файлы ресурсов: это разные области API.

Источник: doc/mod/main.md, bin/mod.js, bin/mod-legacy-wrapper.js.