Хотел бы сегодня поговорить о говнокоде.

Часто разработчики создают тикеты на сайте по причине, что их опубликованный плагин даже не проходит проверку. Да, мы проверяем плагины, в том числе и код. Мы не всегда придираемся к шатким решениям, но определённый кринж сразу улетает в мусорку.
После публикации зайдите на страницу своего плагина и сами посмотрите на описание. Всё ли в нём понятно? Есть ли описание команд, прав, функций, методов установки и плейсхолдеров? Если всё это есть — отлично. Если нет... Ну, это уже игра в рулетку.
Но дьявол кроется в мелочах, о которых многие начинающие «разработчики» даже не задумываются.
Например, как вообще работает Minecraft? В основном он работает в одном потоке. И если вы вклиниваете в этот поток свой плагин с синхронными операциями и синхронной работой с базой данных, то довольно часто будете видеть нечто подобное:
Не бойтесь его. Paper вам подсказывает:
«The server has not responded for 10 seconds! Creating thread dump»
Paper специально завёл watchdog-поток, который следит за главным потоком сервера. Если тот не успел сделать тик за ~10 секунд — watchdog орёт и сбрасывает дамп стека. И в 95% случаев в этом дампе светится именно твой плагин.
Если ты в этом потоке делаешь:
Я не говорю сейчас про «красивый ООП» и архитектуру в целом. Я говорю о реальных багах, которые вы сами впихиваете в код (допустили, что нейронка это вам написала), а потом удивляетесь, почему плагин не приняли или почему он убивает сервера.
Сколько уже можно повторять: читайте документацию. Вот она, специально для вас: plugin.yml | PaperMC Docs
С Paper 1.19+ (и всех современных форках) вам не нужно пихать библиотеки внутрь своего jar через maven-shade-plugin или shadowJar. Это устаревший и вредный подход.
Теперь можно просто прописать нужные библиотеки в plugin.yml, и Paper сам их скачает и подгрузит при включении плагина:
gradle
Maven
provided - и говорит что не нужно его совать в jar
Не нужно использовать shadowJar для этих библиотек — они будут подгружаться отдельно.
Размер твоего плагина сильно уменьшится.
Меньше конфликтов с другими плагинами (если у кого-то уже есть эта версия библиотеки — Paper умнее справляется).
Если библиотека уже есть в Paper (Adventure, Kyori, некоторые Guava-классы) — её не нужно прописывать.
Многие до сих пор пихают в jar по 5–10 мегабайт лишних библиотек, хотя можно было просто написать 3 строчки в plugin.yml.
Из-за этого плагин становится тяжелее, дольше загружается и чаще конфликтует.
Так что если ты используешь внешние библиотеки — переходи на libraries: в plugin.yml.
Это уже давно стандарт.
Не заставляйте нас проверять каждый раз тонны кода библиотек на... плохой код.
И после этого пишите свой ТЗ, про как на FunTime.
Такой промпт уже сильно повышает шансы, что нейросеть не напишет тебе код, который потом убьёт тикрейт или будет падать при 30+ игроках.

Часто разработчики создают тикеты на сайте по причине, что их опубликованный плагин даже не проходит проверку. Да, мы проверяем плагины, в том числе и код. Мы не всегда придираемся к шатким решениям, но определённый кринж сразу улетает в мусорку.
Почему мой плагин удалили?
Описание
Не будем говорить про оформление ресурса, хотя оно тоже важно и влияет на публикацию. Просто скажу пару слов об этом.После публикации зайдите на страницу своего плагина и сами посмотрите на описание. Всё ли в нём понятно? Есть ли описание команд, прав, функций, методов установки и плейсхолдеров? Если всё это есть — отлично. Если нет... Ну, это уже игра в рулетку.
Скачивание
Никаких Telegram-каналов и Discord-серверов. Если уж использовать внешнюю ссылку, то мы предпочитаем GitHub.Код... вот где зарыта хрюшка
Я всё понимаю: век технологий, и код уже не всегда хочется писать самому. Это понятно. Но когда вы пишете код через нейронку, ей, по большому счёту, всё равно. Она напишет. И это даже может работать.Но дьявол кроется в мелочах, о которых многие начинающие «разработчики» даже не задумываются.
Например, как вообще работает Minecraft? В основном он работает в одном потоке. И если вы вклиниваете в этот поток свой плагин с синхронными операциями и синхронной работой с базой данных, то довольно часто будете видеть нечто подобное:
Код:
[02:04:00] [Paper Watchdog Thread/ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - 1.21.3-66-afb5b13 (MC: 1.21.3) ---
[02:04:00] [Paper Watchdog Thread/ERROR]: The server has not responded for 10 seconds! Creating thread dump
[02:04:00] [Paper Watchdog Thread/ERROR]: ------------------------------
[02:04:00] [Paper Watchdog Thread/ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[02:04:00] [Paper Watchdog Thread/ERROR]: ------------------------------
[02:04:00] [Paper Watchdog Thread/ERROR]: Current Thread: Server thread
[02:04:00] [Paper Watchdog Thread/ERROR]: PID: 129 | Suspended: false | Native: true | State: RUNNABLE
[02:04:00] [Paper Watchdog Thread/ERROR]: Stack:
[02:04:00] [Paper Watchdog Thread/ERROR]: java.base@21.0.5/sun.nio.ch.UnixFileDispatcherImpl.write0(Native Method)
... (и дальше куча строчек)Не бойтесь его. Paper вам подсказывает:
«The server has not responded for 10 seconds! Creating thread dump»
Paper специально завёл watchdog-поток, который следит за главным потоком сервера. Если тот не успел сделать тик за ~10 секунд — watchdog орёт и сбрасывает дамп стека. И в 95% случаев в этом дампе светится именно твой плагин.
Если ты в этом потоке делаешь:
- синхронный запрос в БД (Connection.createStatement().executeQuery(...))
- синхронный HTTP-запрос
- тяжёлую обработку файлов
- сложные расчёты без выноса в другой поток
- даже просто Thread.sleep() по приколу
Что делать правильно (чтобы не было такого)
- Всё тяжёлое — только асинхронно.
- BukkitRunnable#runTaskAsynchronously
- CompletableFuture.supplyAsync
- В новых версиях — виртуальные потоки (Thread.startVirtualThread)
- Никогда не делай синхронные запросы в:
- onEnable / onDisable
- Listener'ах
- CommandExecutor'ах (если не используешь setExecutor с async)
- Используй нормальные пулы соединений (HikariCP) + prepared statements.
- Если плагин маленький — хотя бы выноси работу с файлами/БД в отдельный поток.
Я не говорю сейчас про «красивый ООП» и архитектуру в целом. Я говорю о реальных багах, которые вы сами впихиваете в код (допустили, что нейронка это вам написала), а потом удивляетесь, почему плагин не приняли или почему он убивает сервера.
Библиотеки
Да, библиотеки тоже влияют на проверку, хоть и не так критично, как синхронный код.Сколько уже можно повторять: читайте документацию. Вот она, специально для вас: plugin.yml | PaperMC Docs
С Paper 1.19+ (и всех современных форках) вам не нужно пихать библиотеки внутрь своего jar через maven-shade-plugin или shadowJar. Это устаревший и вредный подход.
Теперь можно просто прописать нужные библиотеки в plugin.yml, и Paper сам их скачает и подгрузит при включении плагина:
YAML:
name: MySuperPlugin
version: 1.0.0
main: com.example.plugin.Main
api-version: 1.21
libraries:
- com.github.ben-manes.caffeine:caffeine:3.2.3
- org.apache.commons:commons-math3:3.6.1
- com.zaxxer:HikariCP:5.1.0Как и откуда брать эти строчки
- Идёшь на один из этих сайтов:
- Ищешь нужную библиотеку (например, caffeine, hikaricp, commons-lang3 и т.д.).
- Берёшь Maven координаты в формате:
groupId:artifactId:version
Примеры популярных библиотек, которые часто используют:Библиотека Координаты для plugin.yml Комментарий Caffeine com.github.ben-manes.caffeine:caffeine:3.2.3 Лучший кэш HikariCP com.zaxxer:HikariCP:5.1.0 Нормальный пул соединений (Вроде даже в ) Commons Lang 3 org.apache.commons:commons-lang3:3.14.0 Удобные утилиты Commons Math 3 org.apache.commons:commons-math3:3.6.1 Математика Gson com.google.code.gson:gson:2.11.0 Paper и так её даёт, можно не указывать Adventure — Уже встроена в Paper, не трогай
Важные моменты
В build.gradle / pom.xml эти библиотеки должны быть как compileOnly (или provided), а не implementation. Иначе они всё равно попадут в jar.gradle
Код:
dependencies {
compileOnly("com.zaxxer:HikariCP:7.0.2")
} Код:
<dependencies>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>7.0.2</version>
<scope>provided</scope>
</dependency>
</dependencies>Не нужно использовать shadowJar для этих библиотек — они будут подгружаться отдельно.
Размер твоего плагина сильно уменьшится.
Меньше конфликтов с другими плагинами (если у кого-то уже есть эта версия библиотеки — Paper умнее справляется).
Если библиотека уже есть в Paper (Adventure, Kyori, некоторые Guava-классы) — её не нужно прописывать.
Многие до сих пор пихают в jar по 5–10 мегабайт лишних библиотек, хотя можно было просто написать 3 строчки в plugin.yml.
Из-за этого плагин становится тяжелее, дольше загружается и чаще конфликтует.
Так что если ты используешь внешние библиотеки — переходи на libraries: в plugin.yml.
Это уже давно стандарт.
Не заставляйте нас проверять каждый раз тонны кода библиотек на... плохой код.
Хотелось бы ещё добавить вот что.
Я понимаю, что сейчас очень многие пишут код с помощью нейросетей. Это не ок, но я не против. Но если уже просить ИИ писать плагин, то хотя бы стоит дать ему нормальный системный промпт перед началом. Иначе он напишет то, что «в среднем работает», а не то, что правильно для Minecraft.Вот пример хорошего промпта, который можно скопировать и использовать:
Код:
Ты — опытный разработчик Minecraft-плагинов для Paper 1.21+.
Пиши код максимально качественно и по лучшим практикам:
- Чётко соблюдай принципы ООП, разделяй ответственность между классами.
- Никогда не выполняй тяжёлые или блокирующие операции (запросы в БД, HTTP, чтение/запись файлов и т.д.) в главном потоке сервера. Всё должно быть асинхронным.
- Если используешь внешние библиотеки — подключай их через секцию `libraries` в plugin.yml[](https://docs.papermc.io/paper/dev/plugin-yml/#libraries). Не шейдь их в jar без крайней необходимости.
- Не хардкодь строки и настройки. Используй конфигурационные файлы (config.yml) и отдельный lang.yml для всех сообщений игрокам.
- Следи за потокобезопасностью. Не модифицируй коллекции без синхронизации.
- Используй правильную структуру пакетов и понятные названия классов и методов.
- Добавляй комментарии и JavaDoc там, где это действительно помогает понять код.
- Предпочитай современные подходы: CompletableFuture, виртуальные потоки (где уместно), records, pattern matching и т.д.Такой промпт уже сильно повышает шансы, что нейросеть не напишет тебе код, который потом убьёт тикрейт или будет падать при 30+ игроках.
Последнее редактирование: