Разработка игрБэкендJava / Kotlin

Как написать первый плагин Minecraft на Java: команда /hello

Создаём Paper-плагин на Java, регистрируем команду /hello через plugin.yml, собираем JAR Gradle и проверяем загрузку на локальном тестовом сервере.

Кодик

Автор

6 мин чтения

Первый Paper-плагин состоит из трёх обязательных частей: Java-класса, plugin.yml и JAR, собранного под совместимую версию сервера. Мы добавим команду /hello, увидим сообщение в игре и разберём, почему плагин может собратьcя успешно, но не загрузиться из-за main class, api-version или Java toolchain.

Плагин выполняется внутри Minecraft-сервера и расширяет его через Paper API. Он не является модом клиента и не меняет саму игру на компьютере игрока. Сервер при запуске сканирует папку plugins, читает plugin.yml из JAR, загружает указанный main class и вызывает onEnable. Внутри него мы регистрируем обработчик команды hello.

1Описываем

plugin.yml сообщает имя, main class, api-version и команду hello.

2Регистрируем

Класс extends JavaPlugin и назначает executor во время onEnable.

3Собираем

Gradle создаёт JAR, который копируется в plugins локального Paper-сервера.

Как Paper находит и запускает плагин

Проект использует Gradle Kotlin DSL. build.gradle.kts добавляет официальный Paper repository, compileOnly зависимость и Java toolchain, соответствующий текущей документации. Исходник лежит по пути src/main/java/dev/kodik/hello/HelloPlugin.java и начинается package dev.kodik.hello.

ЭтапЧто происходитПризнак результата
BuildGradle компилирует Java против Paper APIСоздан build/libs/*.jar
DiscoveryPaper читает plugin.yml внутри JARИмя и main найдены
EnableСервер создаёт HelloPlugin и вызывает onEnableВ логе нет ошибки загрузки
CommandИгрок вводит /hello, executor отвечаетСообщение видно в чате

У проекта есть один главный маршрут: получить входные данные, проверить их, выполнить действие и показать результат. Если каждый этап можно проверить отдельно, ошибка перестаёт быть загадкой.

Как Paper запускает плагин
От входных данных до видимого результата. Descriptor связывает файл сервера с Java-классом

Версия сервера, API и JDK должны образовывать один набор. Не берите номер зависимости из старого ролика. Откройте Project setup Paper для своей версии, выберите требуемый Java toolchain и укажите совместимый api-version.

Создаём Gradle-проект и команду /hello

Создайте в IntelliJ проект Gradle с Kotlin DSL. Структура каталогов и файлы есть в исходниках статьи. На момент проверки актуальная документация Paper показывает ветку 26.2 и Java toolchain 25, но эти числа нестабильны. Сверьте их перед сборкой. После добавления файлов выполните ./gradlew build или gradlew.bat build на Windows.

package dev.kodik.hello;

import java.util.Objects;
import org.bukkit.plugin.java.JavaPlugin;

public final class HelloPlugin extends JavaPlugin {
    @Override
    public void onEnable() {
        Objects.requireNonNull(getCommand("hello"), "hello is missing in plugin.yml")
            .setExecutor((sender, command, label, args) -> {
                sender.sendMessage("Привет, " + sender.getName() + "! Плагин работает.");
                return true;
            });

        getLogger().info("HelloPlugin включён");
    }
}
Что должно произойти после запуска
  • Gradle завершает build и создаёт JAR в build/libs.
  • После копирования JAR и запуска Paper в логе появляется «HelloPlugin включён».
  • Команда /plugins показывает плагин как загруженный.
  • Команда /hello от игрока и консоли возвращает персональное сообщение.

Objects.requireNonNull превращает забытый раздел commands в точную ошибку во время запуска. Без него getCommand может вернуть null, а причина потеряется в другом месте.

Собранный JAR и реально загруженный плагин
Что отличает устойчивый проект от случайного успеха. Лог загрузки дополняет успешную компиляцию

Почему package, main и пути должны совпасть

compileOnly означает, что Paper API нужно для компиляции, но не упаковывается в JAR: реализация уже существует на сервере. plugin.yml попадает в корень JAR как ресурс. Поле main содержит полное имя класса вместе с package. Paper использует class loader, создаёт экземпляр и вызывает lifecycle-методы. getCommand ищет декларацию hello в YAML.

ЧастьОтветственностьЧто проверить
build.gradle.ktsВыбирает API и Java toolchainВерсии совместимы с сервером
Java packageЗадаёт полное имя классаПуть и package совпадают
plugin.ymlОписывает плагин и commandmain написан без ошибки
onEnableРегистрирует поведение после загрузкиКоманда существует до getCommand
JARДоставляет class и resources серверуЛежит в plugins до старта

Не перезагружайте плагины командой /reload во время разработки: многие плагины и ресурсы не рассчитаны на такой lifecycle. Останавливайте тестовый сервер, заменяйте JAR и запускайте снова. Не разрабатывайте на прод-сервере с игроками.

Успешный Gradle build не доказывает загрузку на сервере. Компилятор не проверяет, что plugin.yml указывает правильный main и api-version подходит серверу. Всегда читайте лог полного запуска Paper.

Собираем JAR и читаем серверный лог

Соберите JAR и до копирования откройте его как ZIP: plugin.yml должен лежать в корне, а HelloPlugin.class по пути dev/kodik/hello. Запустите локальный тестовый сервер и примите лицензионное соглашение Minecraft только если согласны с его условиями. Выполните /hello из игры и консоли.

Проверка своими руками
  1. Соберите JAR и найдите внутри class и plugin.yml.
  2. Запустите отдельный локальный Paper-сервер и прочитайте enable-лог.
  3. Выполните /hello игроком и консолью.
  4. Сломайте main class, зафиксируйте ошибку и восстановите файл.
  5. Добавьте необязательный аргумент имени с проверкой длины.
  6. Остановите сервер перед заменой JAR и повторите запуск.
Готово, если выполняются все пункты
  • JAR содержит правильную структуру.
  • Paper загружает плагин без stack trace.
  • /hello отвечает двум типам sender.
  • Версии API, сервера и JDK задокументированы.

Первый плагин готов не после компиляции, а после полного цикла: JAR собран, descriptor прочитан, onEnable выполнен, команда проверена и ошибка конфигурации понятна.

Четыре проверки команды /hello
Четыре проверки перед следующим шагом. Версии являются частью воспроизводимого проекта

Куда развивать первый игровой плагин

Следующим шагом добавьте permission для /hello и проверьте игрока с правом и без него. Затем вынесите формат сообщения в config.yml и используйте saveDefaultConfig. Для игровой механики подпишитесь на одно событие, например PlayerJoinEvent, и не смешивайте его с командой в гигантском классе.

Как изучить тему в Кодике

В Кодике начните с классов, методов и package Java. Затем соберите обычный JAR без Minecraft. После этого подключите Paper API и разберите lifecycle. Игровая мотивация полезна, но базовые конструкции должны оставаться узнаваемыми.

ШагЧто изучить в КодикеМини-проверка
1Классы и методы JavaСоздать HelloPlugin и переопределить onEnable
2Package и структура проектаСопоставить путь и полное имя класса
3Gradle dependencyОбъяснить compileOnly
4plugin.ymlСвязать main и commands с кодом
5Тестовый серверСобрать, загрузить и проверить /hello

Не пытайтесь запомнить весь API. В тренажёре Кодика сначала воспроизведите чистую логику без библиотеки, затем восстановите подключение и обработку ошибок. Финальный тест: объяснить проект по памяти и добавить одну свою функцию.

main class не совпадает с package

Укажите полное имя класса и проверьте расположение исходника.

Взята случайная версия API

Сверьте версию Paper-сервера, api-version и требуемый JDK по актуальной документации.

plugin.yml лежит рядом с Java

Ресурс должен находиться в src/main/resources и попасть в корень JAR.

JAR заменяют на работающем сервере

Остановите тестовый сервер, замените файл и запустите заново вместо /reload.

Сверьтесь с первичным источником. Команды, версии и ограничения примера проверяйте по официальной документации Paper: Project setup. Если интерфейс изменился, первичная документация важнее старого скриншота.

Что получится в итоге

Готовый результат: Как написать первый плагин Minecraft на Java: команда /hello
Gradle собирает JAR, Paper читает plugin.yml, вызывает onEnable и новая команда /hello отвечает игроку прямо в серверном чате.

Короткие ответы
Почему Paper API используется как compileOnly?

API нужно компилятору, а реализация уже находится на сервере и не должна дублироваться внутри JAR.

Что связывает plugin.yml и Java-класс?

Поле main с полным именем package.class, а также имя команды hello для getCommand.

Почему нельзя ограничиться успешным build?

Ошибки descriptor, api-version и class loading проявляются только при загрузке сервером.

Как понять, что проект действительно работает?

Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.

Можно ли начать с готового кода из статьи?

Да. Добейтесь результата, измените одно правило и соберите ключевой файл заново без копирования.

Закрепите Java на команде, которую можно запустить в игре

Классы и методы закрепите в курсе Java. Типичную ошибку объекта разберите в статье про NullPointerException.

Проект сохраните по инструкции про GitHub, а терминал повторите в материале для новичков.