Глобальный квест — общий прогресс всех игроков¶
Серверный ивент: «вместе уничтожить 10 000 зомби», «общими усилиями собрать 50 000 алмазов», «построить городскую стену». Все игроки видят один и тот же счёт. Когда он достигает цели — задача засчитывается всем.
InkQuest не имеет встроенного понятия «глобального квеста»: у каждого игрока — собственный трекер. Но Minecraft позволяет хранить scoreboard-счёт под именем виртуального игрока (любая строка, не связанная с реальным аккаунтом). Если все участники аккумулируют свой вклад в одну такую переменную — получится общий прогресс.
Зачем нужен этот паттерн¶
- Серверные ивенты с коллективной целью. Создаёт чувство общего дела — лучшего, чем личные ачивменты.
- Гонки фракций. Две команды соревнуются, чей счёт быстрее достигнет цели.
- Постоянная серверная кампания. Долгосрочные многоэтапные ивенты, тянущиеся неделями.
- «Стена-страх» в Survival. Виден общий счётчик («осталось 47 минут до Ночи»), создаёт давление.
Как это работает в одном предложении¶
condition.success смотрит на scoreboard виртуального игрока #GLOBAL через тип global_score. Каждый участник через on.tick переносит свой личный вклад в этот общий счёт. Когда #GLOBAL достигает цели — success срабатывает у каждого участника независимо.
Шаг 1. Создаём квест с глобальным условием¶
data/legion_fall/quests/main.json:
{
"version": 3,
"variant": 0,
"title": "Падение легиона",
"description": "Тьма наступает. Каждый удар по нечисти приближает конец войны.",
"tasks": {
"kill_zombies": {
"title": "Сразить 10 000 зомби",
"condition": {
"success": {
"type": "global_score",
"objective": "zombies_killed_total",
"to": 10000
}
},
"on": {
"load": {
"functions": ["legion_fall:init"]
},
"tick": {
"functions": ["legion_fall:accumulate"]
},
"success": {
"functions": ["legion_fall:reward"]
}
}
}
},
"stages": [["kill_zombies"]]
}
Главное:
"type": "global_score"— счёт фиксированного holder'а, а не контекстного игрока. При загрузке задачи каждым участником счёт не сбрасывается — это принципиальное отличие отscore."player"не указан — используется дефолт"#GLOBAL". Можно задать любое имя (SERVER,EVENT_KARMA,#тьма) — главное, чтобы оно совпадало с тем, кудаon.tick-функция аккумулирует вклад.
Шаг 2. Заводим scoreboards в функции on.load¶
Загружается один раз при первой выдаче задачи у каждого игрока.
data/legion_fall/functions/init.mcfunction:
scoreboard objectives add zombies_personal minecraft.killed:minecraft.zombie
scoreboard objectives add zombies_killed_total dummy
scoreboard players set @s zombies_personal 0
Три строки: 1. Личный счётчик убийств зомби (статистика Minecraft). 2. Общий счётчик (dummy — управляем вручную). 3. Сброс личного счёта при старте квеста, чтобы предыдущие убийства не зачлись.
Команды
scoreboard objectives add ...безопасно вызывать многократно — если objective уже есть, ничего не сломается.
Шаг 3. Накопление в on.tick¶
data/legion_fall/functions/accumulate.mcfunction:
scoreboard players operation GLOBAL zombies_killed_total += @s zombies_personal
scoreboard players set @s zombies_personal 0
Каждый тик личные убийства игрока прибавляются к общему счёту и сразу обнуляются. Так каждое убийство учитывается ровно один раз.
Шаг 4. Награда в on.success¶
data/legion_fall/functions/reward.mcfunction:
give @s minecraft:netherite_helmet
tellraw @s {"text":"Легион пал. Спасибо за участие!","color":"gold"}
Эта функция вызовется у каждого участника, как только GLOBAL-счётчик достигнет 10000.
Шаг 5. Раздаём квест всем участникам¶
В функции #minecraft:load (или при заходе нового игрока на сервер):
Или вручную: /execute as @a run quest give @s legion_fall:main.
Проверка¶
- Выдай квест двум игрокам (или себе + alt-аккаунт).
- Убей нескольких зомби каждым игроком.
- Проверь общий счёт:
/scoreboard players get GLOBAL zombies_killed_total— он должен расти. - Для быстрой проверки добавь руками:
/scoreboard players add GLOBAL zombies_killed_total 10000. - На следующем тике задача завершится у обоих игроков одновременно. ✅
Что важно понимать¶
Каждый игрок — отдельный трекер¶
InkQuest хранит активную задачу для каждого участника независимо. Условие score смотрит на общий объект scoreboard. Когда GLOBAL zombies_killed_total достигает цели, следующий тик каждого участника увидит выполненное условие — задача завершится у каждого из них, и хук on.success сработает у каждого индивидуально.
Новый игрок видит уже накопленный прогресс¶
Если выдать квест посреди ивента — игрок сразу увидит «9 500 / 10 000». Прогресс хранится в scoreboard, а не в данных квеста, поэтому он «общий по построению».
Только участники вносят вклад¶
Хук on.tick срабатывает у тех, кто отслеживает квест. Если квест нужно сделать обязательным для всех — выдавай его автоматически (см. шаг 5), либо в on.success стартового квеста по входу на сервер.
condition.failure тоже глобален¶
Если задать failure через тот же score (например, «если за 30 минут не успели»), провал прилетит всем одновременно — что и нужно для ивента. См. Задача с двумя исходами про эту механику.
Подводные камни¶
⚠️ Не используй score вместо global_score¶
Если ты поставишь тип score и захочешь смотреть на счёт по holder'у через player — этого поля у score больше нет. Используй global_score: он именно для этого и создан. Тип score всегда смотрит только на счёт контекстного игрока и при reset: true (дефолт) записывает from в scoreboard при каждом load — что сбросило бы общий счёт при входе каждого нового игрока.
Дроп квеста не сбросит scoreboard¶
Это разные слои хранения. Данные квеста живут в сейве мира, scoreboard живёт сам по себе. При перезапуске ивента обнуляй objective явно:
on.success срабатывает у каждого игрока¶
Если функция должна выполниться один раз на мир (например, открыть портал, заспавнить босса) — защити её через scoreboard-флаг:
# Первой строкой — поднимаем счётчик
scoreboard players add GLOBAL boss_spawned 1
# Остальная логика — только если первый
execute if score GLOBAL boss_spawned matches 1 run summon minecraft:wither ~ ~ ~
execute if score GLOBAL boss_spawned matches 1 run tellraw @a {"text":"Босс пробудился!","color":"red"}
Первый сработавший игрок поднимет счётчик с 0 до 1 и выполнит логику; остальные поднимут его выше 1 и не пройдут условие.
Игроки офлайн не вносят вклад в реальном времени¶
Их on.tick не работает, пока они не зайдут на сервер. Это не мешает — оффлайн-участник просто «догонит» остальных, когда вернётся, или присоединится к уже частично заполненному прогрессу.
Расширения¶
Видимый счётчик в sidebar¶
%%Есть progress bar, так что счёт уже видно%%
Чтобы все игроки видели общий прогресс — выведи его на боковую панель:
scoreboard objectives modify zombies_killed_total displayname "Зомби убито"
scoreboard objectives setdisplay sidebar zombies_killed_total
Теперь справа у каждого игрока висит «Зомби убито: GLOBAL 9234». Это нативная Minecraft-механика, InkQuest тут не нужен.
Гонка фракций¶
%%Лучше сделать пустую обязательную задачу, а фракции опциональными, в success условие score (как сейчас), а в failed условие optionals с min 1. Получится универсальнее и расширяемо на любое число команд%%
Два виртуальных игрока (FACTION_RED, FACTION_BLUE), два условия global_score:
"condition": {
"success": {
"type": "global_score",
"objective": "war_score",
"player": "FACTION_RED",
"to": 10000
},
"failure": {
"type": "global_score",
"objective": "war_score",
"player": "FACTION_BLUE",
"to": 10000
}
}
Выдай этот квест игрокам красной фракции, в on.tick накапливай в FACTION_RED. Параллельный квест с обратным расположением полей — для синей. Победит та, что первой набирает 10 000.
Многошаговый ивент¶
Несколько обязательных задач в одном квесте, каждая со своим GLOBAL-счётчиком — этапы прогрессии всей серверной кампании.
Игроки коллективно проходят по этапам: построили стену → заполняем амбары → защищаемся от орды. Каждый этап со своим глобальным счётчиком и своей наградой в on.success.
«Уникальный» вклад¶
Если каждый игрок должен внести вклад не более одного раза (например, «голосование 100 игроков») — не используй накопление через on.tick. Вместо этого: в специальной функции (например, по нажатию кнопки) ставится тег voted, и тогда:
Где count_vote инкрементит GLOBAL и ставит counted. Так дублирования не будет.
%%Тут хотелось бы ещё содержимое event:count_vote увидеть%%
См. также¶
- Условия выполнения задачи — спецификация условий
scoreиglobal_score - Хуки жизненного цикла задачи — спецификация хуков
load,tick,successи других, что используются здесь - Задача с двумя исходами — как добавить таймер провала для ивента
- Повторяемый квест — для еженедельных ивентов с перезапуском