Создание квестов
Пример квеста
Этот упрощённый пример использует формат поставляемого с плагином test_quest.yml.
Создавайте файлы .yml с уникальными именами в plugins/EliteMobs/customquests/ относительно папки сервера. Загрузите квест и указанный в нём контент командой /em reload, затем назначьте квест NPC, как показано ниже.
test_quest.yml
isEnabled: true
customObjectives:
Objective1:
amount: '1'
filename: test_boss.yml
objectiveType: KILL_CUSTOM
customRewards:
- filename=magmaguys_toothpick.yml:amount=1:chance=1
name: "&aKill the Test Boss"
questLore:
- "&cEnd the test boss' reign of terror!"

На снимке показан старый интерфейс книги. /em alt меняет предпочтение меню: игроки Java с этой настройкой получают книги до Minecraft 1.21.6 и диалоги Minecraft в более новых версиях. Игроки Bedrock и выбравшие меню инвентаря используют интерфейс инвентаря.
Этот пример квеста даст игрокам задание убить 1 test_boss.yml. (Фактическое имя босса, отображаемое в трекере квестов, будет взято из поля name:, заданного в test_boss.yml.) А в награду за выполнение квеста они получат 1 Magmaguy's Toothpick.
Все цели активируются одновременно при принятии квеста; ключи Objective1, Objective2 и подобные не задают порядок. Для награды нужно выполнить все цели. По умолчанию после этого квест сдают NPC. При requireQuestTurnIn: false в Quests.yml выполнение целей сразу запускает попытку завершения, включая проверку и расход собираемых предметов. maximumActiveQuests по умолчанию ограничивает число принятых квестов десятью.
Создание пользовательских квестов
isEnabled
Задаёт, включён ли квест.
| Ключ | Значения | По умолчанию |
|---|---|---|
isEnabled | Логическое значение | true |
Пример
isEnabled: true
customObjectives
Задаёт цели квеста.
| Ключ | Значения | По умолчанию |
|---|---|---|
customObjectives | Особый формат [1] | нет |
Для многофазового босса указывайте файл первой фазы. Прогресс засчитывается при смерти босса, а не при каждой смене фазы. KILL_CUSTOM проверяет имя файла и не использует questLevel как минимальный уровень убитого босса.
Примеры
KILL_CUSTOM:
customObjectives:
Objective1:
amount: '1'
filename: my_cool_boss.yml
objectiveType: KILL_CUSTOM
DIALOG:
customObjectives:
Objective1:
dialog:
- "&a[Dialog NPC] &fCome here often?"
- "&7&oI should eat more apples."
filename: dialog_npc.yml
npcName: Dialog NPC
location: at dialog location.
objectiveType: DIALOG
FETCH_ITEM:
Цели сбора считают соответствующие метки пользовательских предметов EliteMobs в инвентаре. При сдаче все такие цели проверяются по одному снимку инвентаря до удаления предметов и выдачи наград. Если две цели требуют один предмет, нужно суммарное количество: одна стопка не может удовлетворить обе цели одновременно. Выбрасывание предмета может снова сделать выполненную цель незавершённой.
customObjectives:
Objective1:
amount: '99'
itemName: Red Apples
filename: my_quest_item_red_apples.yml
objectiveType: FETCH_ITEM
ARENA:
customObjectives:
Objective1:
objectiveType: ARENA
filename: my_arena.yml
name: "Complete the Arena"

Особый формат [1]
Развернуть таблицу
Пользовательские цели создаются с использованием следующих значений:
| Ключ | Описание |
|---|---|
objectiveType | Тип цели: KILL_CUSTOM — убийство пользовательского босса, FETCH_ITEM — сбор пользовательского предмета, DIALOG — разговор с NPC, ARENA — прохождение арены, CLASS_UNLOCK — проверка открытия класса. |
filename | Обязательное имя файла .yml босса, предмета, NPC для разговора, арены или наставника класса. Указывайте загруженное определение, а не отображаемое имя. Цель без filename либо с отсутствующим или неизвестным objectiveType отключает весь квест с предупреждением в консоли. Неверный CLASS_UNLOCK остаётся в квесте, но выполнить его нельзя. Исправьте все предупреждения до выдачи квеста. |
amount | Положительное целое число боссов или предметов; по умолчанию 1. Значение меньше 1 отключает квест. Для DIALOG, ARENA и CLASS_UNLOCK цель равна единице, это поле игнорируется. |
dialog | Только для DIALOG — реплики, которые NPC произносит, когда игрок с ним разговаривает. |
location | Только для DIALOG — произвольная текстовая подсказка о том, где находится NPC; показывается как $location в строке-сводке меню квестов. |
name / npcName / itemName | Необязательные псевдонимы подписи для FETCH_ITEM, DIALOG, ARENA и CLASS_UNLOCK. Задавайте только один. Все переводятся и позволяют использовать особую формулировку или скрыть информацию. Без замены FETCH_ITEM использует переведённое имя предмета, а DIALOG — имя NPC. KILL_CUSTOM использует имя из конфигурации босса. |
class | Только CLASS_UNLOCK: ID формы класса, например adventurer. |
Задавайте непустую таблицу customObjectives с уникальным ключом для каждой цели (Objective1, Objective2, ...). Имена полей чувствительны к регистру, типы целей используют значения в верхнем регистре из таблицы. Старые строки вида KILL_CUSTOM:filename=X.yml:amount=Y автоматически преобразуются в новый формат при первой загрузке и сохраняются на диск.
У подписей целей отдельные записи перевода: имя файла квеста и путь вроде customObjectives.Objective1.itemName. Переведите эту запись в языковом CSV, даже если сам предмет уже переведён. Если перевода нет, остаётся исходная подпись, чтобы не раскрывать скрытое имя предмета. Исходный текст остаётся в YAML квеста, существующие переводы сохраняются.
Поведение FETCH_ITEM
FETCH_ITEM распознаёт метку имени файла предмета, а не материал, видимое имя или описание. Учитываются предметы, полученные до принятия, в том числе в слотах брони и второй руки. Принятие, подбор или выбрасывание подходящих предметов и награды квестов запускают пересчёт на следующем тике. Другие изменения инвентаря могут отразиться не сразу, но при сдаче он всегда проверяется заново. При успехе нужные предметы расходуются; нехватка суммарного количества отменяет сдачу без частичного изъятия.
DIALOG продвигается при взаимодействии с подходящим NPC, до открытия его обычного меню. Дочитывать диалог не требуется. location — только текстовая подсказка, не координаты компаса. ARENA засчитывает прохождение указанной арены при активном квесте; предыдущие прохождения не учитываются.
Цели открытия класса
CLASS_UNLOCK проверяет класс, открытый через расширенную боевую систему. Сам класс не выдаётся. Например:
customObjectives:
Objective1:
objectiveType: CLASS_UNLOCK
class: adventurer
filename: class_trainer_adventurer.yml
class должен обозначать существующую форму класса. filename направляет отслеживание к наставнику NPC; name необязательно заменяет подпись. Цель равна единице и распознаёт ранее открытый класс, даже если он не выбран сейчас. Развитие классов должно быть доступно; открытие проверяется повторно при завершении. Неверный класс или отсутствующее имя файла наставника оставляет невыполнимую цель, а не пропускается.
Отслеживание и отказ
Игрок может отслеживать только один квест. При autoTrackNextQuestOnCompletion: true в Quests.yml завершение отслеживаемого квеста выбирает другой активный квест с разрешённым отслеживанием на следующем тике. questAutoTrackNextMessage поддерживает $questName. autoTrackQuestsOnAccept тоже включён по умолчанию, но сейчас использует переключатель: принятие квеста при уже включённом отслеживании может остановить его вместо смены цели. При необходимости включите отслеживание снова в меню.
Компас ищет поддерживаемые места: пользовательских боссов, NPC для разговора или наставников, а также боссов и сундуки, в таблицах лута которых есть нужный предмет. Он не находит все возможные источники предметов; у целей арены и динамического убийства нет отдельного поиска места. Для другого мира он может показать подходящий прямой портал или название мира, но не гарантирует проходимый маршрут. Отсутствие места назначения не мешает прогрессу целей.
Обычный отказ требует второго подтверждения. Текст и подсказка задаются через questAbandonConfirmationText и questAbandonConfirmationHover. Отказ удаляет активный квест и его отслеживание, но не запускает блокировку завершения questLockoutMinutes и не выдаёт маркер завершения. Квест можно принять снова при выполнении обычных условий.
Маркеры квестов NPC индивидуальны для каждого игрока и видны в пределах 30 блоков. Компас показывает направление по высоте. Во время диалога через боссбары область занята исключительно им: другие управляемые полосы скрываются, а старая опция hideKeyedBossBarsDuringQuestDialogue удаляется. hideQuestScoreboardDuringQuestDialogue отдельно управляет боковой панелью.
В Java приседание сначала показывает текущую страницу целиком, затем переключает дальше. Диалог накладывает Замедление III не более чем на 30 секунд, а не обездвиживает игрока. Неотменённый урон больше нуля закрывает экраны и диалог квеста. Bedrock получает этот диалог в чате. Для оформления нужны соответствующие ресурсы ресурс-пака.
customRewards
Задаёт награды за квест.
| Ключ | Значения | По умолчанию |
|---|---|---|
customRewards | Универсальный формат лута EliteMobs | нет |
Пример
customRewards:
- currencyAmount=50:amount=1:chance=0.05
- material=COOKED_COD:amount=3:chance=1.0
- filename=magmaguys_toothpick.yml:amount=1:chance=1.0

Пользовательские квесты не создают записи наград автоматически. Если customRewards пуст, эта таблица не выдаёт предметов или валюты; отдельно заданные команды завершения всё равно выполняются. Автоматические записи наград относятся к динамическим квестам.
Масштабируемые предметы наград используют выбранный уровень динамического подземелья или текущий боевой уровень, с вероятностью 10% получить ещё один уровень. Фиксированные и ограниченные предметы сохраняют обычные правила масштабирования. questLevel не задаёт фактический уровень предмета.
Награды за квест выдаются напрямую: предметы попадают сразу в инвентарь игрока (всё, что не помещается, выбрасывается ему под ноги), а валюта добавляется к его балансу. Чтобы выполнять команды при завершении, используйте questCompleteCommands, а не запись лута command=.
Предпросмотр и выдача выполняют отдельные случайные выборы. Показанный случайный предмет или бонус уровня не резервируется за игроком.
questAcceptPermission
Требует один маркер завершения квеста EliteMobs для принятия. Обычное право с тем же именем не удовлетворяет проверке.
| Ключ | Значения | По умолчанию |
|---|---|---|
questAcceptPermission | Строка | нет |
Пример
questAcceptPermission: elitequest.my_permission
questAcceptPermissions
Требует все перечисленные маркеры завершения EliteMobs. Если также задан questAcceptPermission, его маркер тоже обязателен.
| Ключ | Значения | По умолчанию |
|---|---|---|
questAcceptPermissions | Список строк | нет |
Пример
questAcceptPermissions:
- elitequest.my_previous_quest_one.yml
- elitequest.my_previous_quest_two.yml
questLockoutPermission
Задаёт маркер, выдаваемый после успешного завершения. Он может открывать следующие квесты и при нулевом или отрицательном questLockoutMinutes запрещает повтор этого квеста. Отсутствие маркера не отключает положительную блокировку по времени.
| Ключ | Значения | По умолчанию |
|---|---|---|
questLockoutPermission | Строка | нет |
Пример
questLockoutPermission: elitequest.my_quest.yml
questLockoutMinutes
Задаёт, сколько минут игроку придётся ждать, прежде чем он сможет выполнить квест снова.
| Ключ | Значения | По умолчанию |
|---|---|---|
questLockoutMinutes | Целое число | -1 (правило маркера ниже) |
Существуют две системы блокировки, и этот ключ решает, какая из них используется:
- Любое значение выше
0использует трекер блокировки по времени. Игрок заблокирован для этого квеста на указанное число минут после его сдачи, ему сообщается, сколько осталось, когда он пытается взять квест снова, аquestLockoutPermissionигнорируется при проверке доступности. 0или меньше откатывается на устаревший маркерquestLockoutPermission, который выдаётся навсегда при завершении. ЕслиquestLockoutPermissionтоже не задан, квест остаётся повторяемым.
Если заданы оба поля и время положительно, маркер всё равно выдаётся, но исчезает по истечении этого времени. Следующий квест, которому нужен этот маркер, следует принять до его истечения. Временная блокировка хранится по имени файла квеста отдельно от маркера предварительных условий.
Пример
questLockoutMinutes: 60
name
Задаёт имя квеста. Принимает цветовые коды.
| Ключ | Значения | По умолчанию |
|---|---|---|
name | Строка | пусто |
Пример
name: "&aMy Great Quest Name"
questLore
Задаёт описание (lore) квеста, которое будет отображаться во внутриигровом меню квестов.
| Ключ | Значения | По умолчанию |
|---|---|---|
questLore | Список строк | нет |
Пример
questLore:
- "Interesting lore sentence."
- "Yet another interesting lore sentence."

temporaryPermissions
Выдаёт настоящие права Bukkit при принятии квеста и повторно применяет их при восстановлении активного квеста после входа. Завершение квеста или отказ от него снимает эти права, а выход с сервера освобождает их до следующего входа. Каждый квест выдаёт свои узлы отдельно, поэтому два активных квеста могут использовать один узел: завершение одного из них оставляет узел, выданный другим.
Для обычной генерации предмета задайте то же право в его файле. Проверка не охватывает все способы выдачи.
| Ключ | Значения | По умолчанию |
|---|---|---|
temporaryPermissions | Список строк | нет |
Пример
temporaryPermissions:
- elitequest.item_that_should_drop_only_during_quest.yml
questAcceptDialog
Задаёт реплики, которые появляются в чате при принятии квеста.
Когда включены боссбары диалогов квестов, этот список одновременно служит диалогом, который квестодатель произносит в диалоговом окне до принятия квеста. Если он пуст, для этого диалога вместо него используется questLore.
| Ключ | Значения | По умолчанию |
|---|---|---|
questAcceptDialog | Список строк | нет |
Пример
questAcceptDialog:
- "My hero! You are so helpful!"
- "I wish you the best of luck!"

questCompleteMessage
Задаёт диалог сдачи. При useQuestDialogueBossBars в Quests.yml он может появиться до открытия меню сдачи; иначе показывается при успешном завершении. Недавно показанный диалог сдачи не повторяется при завершении. Bedrock получает текст в чате. Само появление диалога не доказывает выдачу награды.
| Ключ | Значения | По умолчанию |
|---|---|---|
questCompleteMessage | Список строк | нет |
Пример
questCompleteMessage:
- "My hero! You have completed my difficult quest!"
- "As a reward you can have this loaf of bread!"

questCompleteCommands
Задаёт команды, которые будут выполнены при завершении квеста. Команды отправляются из консоли, поэтому не включайте ведущий слеш и не рассчитывайте на наличие у игрока прав на них.
Поддерживаемые плейсхолдеры: $player для имени игрока, $getWorld для имени мира, в котором он находится, и $getX, $getY, $getZ для координат его местоположения.
| Ключ | Значения | По умолчанию |
|---|---|---|
questCompleteCommands | Список строк | нет |
Пример
questCompleteCommands:
- say $player has finished a quest at $getX, $getY, $getZ!
- give $player diamond 1
![]()
turnInNPC
Задаёт файл NPC для сдачи. Он может отличаться от квестодателя; если поле пропущено, используется первоначальный NPC. Отдельный принимающий NPC должен использовать interactionType: CUSTOM_QUEST_GIVER, а список его предложений может быть пустым.
| Ключ | Значения | По умолчанию |
|---|---|---|
turnInNPC | Имя файла | нет |
Пример
turnInNPC: my_cool_quest_npc.yml
Выдача квестов
Чтобы назначить квест NPC, который будет выдавать его игрокам, нужно настроить файл NPC, а не файл квеста.
В файле NPC (plugins/EliteMobs/npcs/) добавьте:
interactionType: CUSTOM_QUEST_GIVER
questFileName:
- my_quest.yml
Для NPC, которые выдают несколько квестов:
interactionType: CUSTOM_QUEST_GIVER
questFileName:
- quest_one.yml
- quest_two.yml
Используйте список YAML даже для одного квеста: скаляр questFileName: my_quest.yml не загружается как список предложений. Для открытия списка требуется interactionType: CUSTOM_QUEST_GIVER.
Подробнее о настройке NPC см. документацию по созданию NPC.
trackable
Разрешает ручное и автоматическое отслеживание компасом. false не останавливает прогресс целей, выдачу наград или временные панели прогресса.
| Ключ | Значения | По умолчанию |
|---|---|---|
trackable | Логическое значение | true |
Пример
trackable: true
questLevel
Задаёт уровень квеста. Это всего лишь визуальный ориентир, чтобы игроки могли понять, насколько сложным будет квест. Это никак не изменяет уровни босса, предметов или другие уровни.
| Ключ | Значения | По умолчанию |
|---|---|---|
questLevel | Целое число | 0 |
Пример
questLevel: 10

questAcceptSound
Задаёт звук, который воспроизводится при принятии квеста. Можно воспроизводить как звуки Minecraft, так и звуки из ресурс-пака. Когда он не задан, EliteMobs вместо него проигрывает глобальный звук принятия квеста из SoundsConfig.
| Ключ | Значения | По умолчанию |
|---|---|---|
questAcceptSound | Строка | нет |
Пример
questAcceptSound: entity.experience_orb.pickup

questCompleteSound
Задаёт звук, который воспроизводится при завершении квеста (его сдаче). Можно воспроизводить как звуки Minecraft, так и звуки из ресурс-пака. Когда он не задан, EliteMobs вместо него проигрывает глобальный звук завершения квеста из SoundsConfig.
| Ключ | Значения | По умолчанию |
|---|---|---|
questCompleteSound | Строка | нет |
Пример
questCompleteSound: entity.player.levelup

Поддержка локализации
Следующие поля поддерживают локализацию для многоязычных серверов:
namequestLorequestAcceptDialogquestCompleteMessage- Внутри каждой записи
customObjectives:dialog,name,npcName,itemNameиlocation
Это позволяет вам предоставлять переводы для разных языков на вашем сервере.
Разрешения
Как упоминалось в таблицах выше, права обычно представляют собой Strings или String Lists. Но давайте рассмотрим подробнее, как вы будете использовать их для блокировки и разблокировки квестов.
Важно: questAcceptPermission и questAcceptPermissions проверяют внутренние маркеры EliteMobs, а не обычные права. Завершение квеста с подходящим questLockoutPermission создаёт маркер. Выдача одноимённого права через LuckPerms не открывает квест. temporaryPermissions, напротив, выдаёт настоящие права, пока квест активен.
Допустим, вы создаёте quest_3 в запланированной серии квестов и не хотите, чтобы игроки могли взять quest_3 до того, как они завершат quest_2. Мы настроили бы файл квеста так:
questAcceptPermission: elitequest.quest_2.yml
questLockoutPermission: elitequest.quest_3.yml
Квест 2 должен выдавать elitequest.quest_2.yml через свой questLockoutPermission. Квест 3 требует этот маркер через questAcceptPermission. При неположительной длительности по умолчанию завершение квеста 3 выдаёт постоянный маркер и запрещает повтор. Предложение уже активного квеста другим NPC не создаёт вторую независимую копию.
Если вы хотите сделать квест, который становится доступен только после того, как игроки завершат серию квестов, то вы настроили бы файл квеста так:
questAcceptPermissions:
- elitequest.quest_2.yml
- elitequest.quest_3.yml
- elitequest.quest_4.yml
Чтобы принятие разрешало обычную генерацию предмета, добавьте узел в temporaryPermissions и укажите его же в поле permission предмета.
Например, мы откроем наш файл квеста и добавим следующее:
temporaryPermissions:
- elitequest.my_cool_item.yml
Затем мы откроем файл предмета, в нашем случае my_cool_item.yml, и добавим следующее:
permission: elitequest.my_cool_item.yml
Теперь, пока квест активен, он выдаёт узел, проверяемый при обычной генерации предметов, и снимает его при завершении квеста или отказе от него.
Группы и общий зачёт убийств
Квесты остаются личными: вступление в группу не принимает, не сдаёт и не награждает квесты за других. Когда участнику засчитывается убийство, другие участники онлайн в том же мире и в пределах sharedProgressRange (по умолчанию 128 блоков в Party.yml) также продвигают свои подходящие активные цели убийства, включая конкретных пользовательских боссов.
Предметы сбора, диалоги NPC и цели арен не разделяются. Получателям нужны собственный подходящий активный квест и загруженные данные игрока. Если их матч прошёл этап ожидания или запуска, они должны входить в его первоначальный состав участников. Отдельного сравнения их инстанса с инстансом источника убийства нет; близость в одном мире всё равно обязательна.
Динамические квесты
Динамические квесты — это процедурно генерируемые квесты, которые автоматически создаются и обновляются EliteMobs. В отличие от пользовательских квестов, заданных в конфигурационных файлах, динамические квесты не требуют ручной настройки и адаптируются к прогрессу каждого игрока.
Как они работают
- Квестодатель: используйте NPC с
interactionType: QUEST_GIVER. Его предложения берутся из динамического пула, а неquestFileName. - Тир: ограничьте боевой уровень диапазоном 1–100, разделите на пять целочисленно, затем ограничьте тир диапазоном 1–20. Уровень 45 даёт тир 9. Тир задаёт шаблоны и число убийств, а минимальный уровень врагов берётся из ограниченного боевого уровня игрока.
- Три шаблона на тир: каждый выбирает тип сущности из
questEntityTypesвQuests.yml. Неизвестные типы сущностей и типы без свойств мобов EliteMobs пропускаются с предупреждением, а список без пригодных записей отключает предложения динамических квестов. Каждый шаблон также выбирает число убийств отtier + 1доtier * 10включительно. Подходящий Elite Mob должен быть не ниже минимального уровня; обычный моб Minecraft не считается. - Обновление: все шаблоны обновляются каждые 1200 тиков, примерно 60 секунд при 20 TPS. Существующие квесты и прогресс сохраняются. Меню объединяет их с тремя текущими шаблонами, исключая повторные ID шаблонов, поэтому записей может быть больше трёх.
- Динамические подземелья: вход меняет минимальный уровень врагов, показанный уровень и имя существующих динамических квестов на выбранный уровень в пределах 1–100. Число целей и прогресс сохраняются. Валютная награда не пересчитывается.
- Награды: валюта фиксируется при создании предложения как
floor(questLevel / 2 * targetKillCount). Предмет создаётся обычной системой лута при сдаче, по выбранному уровню динамического подземелья или текущему боевому уровню, с вероятностью 10% прибавить один и итоговым ограничением 1–100. Доступность предметов и правила масштабирования сохраняются; предпросмотр делает отдельный случайный выбор.
