Ожидание события¶
Следующий квест должен открыться не сразу после предыдущего, а когда что-то произойдёт в мире: наступит ночь, игрок дойдёт до места, выполнится ритуал.
Зависимости after выдают следующий квест сразу по завершении предыдущего. Если переход должен быть отложенным — добавь в исходный квест задачу-ждуна.
Зачем нужен этот паттерн¶
- Драматическая пауза. «Сделай дело и жди сигнала» — классический сюжетный приём.
- Синхронизация с миром. Следующий квест зависит от времени суток, погоды, фазы луны, координат игрока.
- Темп истории. Не вываливать на игрока следующее задание сразу — дать ему отдышаться или поисследовать локацию.
Шаг 1. Добавляем финальный этап-ждун в исходный квест¶
Берём обычный квест с задачей guide_caravan и добавляем после неё второй этап с одной задачей. Условие этой задачи — нужное событие.
{
"version": 3,
"variant": 0,
"title": "Караван на закате",
"description": "Караван должен пройти за стену до темноты. Дальше — только ждать.",
"tasks": {
"guide_caravan": {
"title": "Проводить караван за стену"
},
"wait_for_signal": {
"title": "Дождаться ночи",
"description": "На башне обещали зажечь огонь, когда город уснёт.",
"condition": {
"success": { "type": "predicate", "predicate": "ch1:is_night" }
}
}
},
"stages": [["guide_caravan"], ["wait_for_signal"]]
}
Пока задача wait_for_signal не выполнится — квест не закроется, и зависимые от него квесты не откроются.
Шаг 2. Описываем условие ожидания¶
В data/ch1/predicates/is_night.json:
Условие срабатывает, когда время в мире от 13000 до 23000 тиков — то есть ночью.
Любой native Minecraft predicate подойдёт: проверка координат, биома, погоды, инвентаря, прокачки и т.д.
Шаг 3. Зависимый квест — обычная цепочка¶
{
"version": 3,
"variant": 0,
"title": "Огонь над городом",
"description": "Башня зажгла сигнал. Пора отвечать.",
"after": [["ch1:caravan_at_sunset"]],
"tasks": {
"answer_signal": { "title": "Подняться на башню" }
},
"stages": [["answer_signal"]]
}
Никаких отличий от обычной цепочки. Магия — в том, что предыдущий квест теперь завершается не мгновенно, а только после наступления ночи.
Проверка¶
- Выдай первый квест:
/quest give @s ch1:caravan_at_sunset. - Закрой первую задачу:
/quest complete @s ch1:caravan_at_sunset task guide_caravan success. - В книге появится второй этап с задачей «Дождаться ночи».
- Подожди наступления ночи (или
/time set night) — задача завершится сама, квест закроется, второй квест выдастся автоматически.
Когда задача-ждун не подходит¶
Иногда ожидание не должно быть видимым: между сценами герой «разойдётся по делам», без записи в дневнике. Тогда задача-ждун ломает темп — игрок видит в HUD «Дождаться ночи», и это разрушает иммерсию.
Для таких случаев есть две альтернативы.
Альтернатива А: тиковая функция датапака¶
Простейший вариант. Ставим игроку тег, тиковая функция проверяет условие и выдаёт следующий квест.
В первом квесте добавляем тег при завершении:
В файле data/ch1/functions/wait_for_night.mcfunction:
execute as @a[tag=ch1.waiting_for_night] at @s if predicate ch1:is_night run function ch1:advance_to_beacon
В data/ch1/functions/advance_to_beacon.mcfunction:
В data/minecraft/tags/functions/tick.json регистрируем:
Готово: как только наступит ночь у игрока с тегом — он получит следующий квест, без задачи в HUD.
Минус: проверка каждый тик у всех помеченных игроков. Для редких переходов overkill, но для коротких ожиданий (минуты) — норм.
Альтернатива Б: цепочка advancement'ов¶
Более экзотично, но дешевле по нагрузке. Vanilla advancement сам отслеживает условие у конкретного игрока и запускает функцию датапака как награду.
Шаг 1. Advancement-маркер «игрок ждёт». Без trigger'а, без награды — нужен только как «ключ», который выдаётся вручную.
data/ch1/advancements/wait_for_night_armed.json:
Шаг 2. Advancement-«стрелочник» с trigger'ом minecraft:tick и player-predicate'ом на нужное событие. Выдаётся автоматически, как только у игрока есть parent-маркер и сработал predicate.
data/ch1/advancements/wait_for_night_complete.json:
{
"parent": "ch1:wait_for_night_armed",
"criteria": {
"tick": {
"trigger": "minecraft:tick",
"conditions": {
"player": [
{
"condition": "minecraft:time_check",
"value": { "min": 13000, "max": 23000 },
"period": 24000
}
]
}
}
},
"rewards": {
"function": "ch1:advance_to_beacon"
}
}
Шаг 3. Функция, выдающая следующий квест и снимающая маркер:
data/ch1/functions/advance_to_beacon.mcfunction:
Шаг 4. В on.success финальной задачи предыдущего квеста ставится маркер:
data/ch1/functions/arm_night_wait.mcfunction:
Vanilla сам отслеживает условие у игроков с выданным parent'ом. Никаких тиковых функций, никаких записей в дневнике.
Минус: больше файлов, выше порог входа.
Какой способ когда¶
| Сценарий | Способ |
|---|---|
| Хочется, чтобы игрок видел и понимал, чего ждёт | Задача-ждун (шаги 1-3) |
| Ожидание короткое, нужно «незаметно перевести сцену» | Тиковая функция (Альтернатива А) |
| Ожидание долгое или редкое, важна производительность | Advancement-цепочка (Альтернатива Б) |
Подводные камни¶
- Невидимое ожидание — это gap для игрока. Если переход происходит «само» и игрок не понимает, чего от него ждут — он застрянет. Скрытое ожидание оправдано только для коротких или сюжетно подразумеваемых задержек («приди завтра»).
- Статус квеста InkQuest нельзя проверить из predicate. Vanilla player predicate не знает про активные/завершённые квесты — поэтому в advancement-цепочке маркер ожидания приходится создавать самим (через advancement-«ключ» или scoreboard-тег). Это не баг, а граница между ванильной системой и InkQuest.
- Игрок офлайн → задача-ждун замёрла.
conditionпроверяется только для игроков на сервере. Это норма: если у тебя «дождаться полнолуния», игрок просто увидит, что условие сработало, когда вернётся.
Расширения¶
Таймер «реального времени»¶
Если нужно ждать N секунд игрового времени (не суток) — комбинируй задачу-ждун с условием score. Заведи objective dummy, в on.load запиши туда 0, в on.tick прибавляй 1. Условие score >= 1200 сработает через минуту (1200 тиков). Похожая механика, но в обратную сторону, описана в Задача с двумя исходами, раздел «Шаблон A.1 — миссия на время».
Цепочка ожиданий¶
Если переходов несколько — каждый со своим условием — оформи их отдельными этапами в одном квесте: [["guide"], ["wait_night"], ["wait_signal"], ["wait_dawn"]]. Каждый этап откроется по своему условию.
Ожидание группы игроков¶
Если нужно дождаться, пока все активные участники события дойдут до точки — комбинируй с глобальным счётчиком: каждый игрок инкрементит счётчик при входе в зону, условие проверяет score >= N.
См. также¶
- Цепочка квестов — базовый паттерн зависимостей, на котором это построено
- Хуки жизненного цикла задачи — про
on.successи теги - Условия выполнения задачи — какие типы условий подойдут для ожидания