Квесты

Квест как node_type, родственный энкаунтеру: привязан к локациям и NPC, живёт в состояниях, имеет награды и дедлайны. Откладывается до encounter rework (spec-032) — проектировать первого без второго рискованно.


Почему квест — родственник энкаунтера

Квест и encounter — оба узлы сценарного графа:

  • Оба привязаны к локации и NPC.
  • Оба имеют state-машину (encounter: active/completed/skipped; quest: offered/accepted/in_progress/completed/failed).
  • Оба могут содержать вложенные encounter'ы как этапы.
  • Оба являются «контейнерами ценности» (лут, опыт, сюжетный прогресс).

Проектировать квест до того, как encounter stanalized в canonical node (spec-032), означает делать два несовместимых node_type там, где должно быть одно семейство.


Жизненный цикл квеста

offered → accepted → in_progress → completed
                              ↓
                           failed
  • offered — квест существует в мире и известен игрокам (NPC рассказал, листок на доске). В этот момент нода квеста «опубликована» (see visibility-and-sandbox.md).
  • accepted — один или несколько PC взяли квест; создаётся watcher.
  • in_progress — пачка активно работает над квестом.
  • completed / failed — финальные состояния; квест закрывается применением наград или записью провала.

Переходы — события; DM управляет переходами из UI или через лог.


Связи с локациями и NPC

Квест-нода связывается рёбрами:

  • quest → location — «этот квест происходит в этой локации» (зависит от spec-031 Карта).
  • quest → npc — «этот NPC выдаёт / контролирует квест».
  • quest → encounter — «этот encounter — этап квеста»; completion encounter'а может автоматически продвинуть квест.

После encounter rework (spec-032) encounter станет полноценной нодой — тогда quest → encounter ребро ляжет естественно.


Награды и дедлайны

Награды хранятся в nodes.fields.rewards как JSONB: { coins: CoinSet, items: [{node_id, qty}], xp: int, notes: string }. При завершении DM нажимает «Применить награды» — создаются транзакции через существующую approval flow (spec-014).

Дедлайны (в целевой модели) — deadline_at_tick: int от точки отсчёта кампании, как в tick-time-model.md. До появления тиков — deadline_day: int в петле. DM видит «осталось N дней» на странице квеста.


Watchers и «мои активные квесты»

Watcher — ребро pc → quest с типом watching; создаётся когда PC принимает квест. На мобильном листе персонажа (spec-022 v3) раздел «Мои квесты» — фильтр нод по этому ребру.

На странице квеста — список watchers с их текущим прогрессом (в каком состоянии они видят квест, если индивидуальный прогресс нужен).


Three Clue Rule (Alexandrian)

Принцип из thealexandrian.net — обязателен при дизайне квестов для west marches:

«Для любого вывода, который игроки должны сделать, давай им три независимых улики. Тогда потеря одной не блокирует прогресс.»

В продукте это означает: у квеста поле clues: [] — список нод или текстовых намёков, из которых игроки могут вывести следующий шаг. DM видит сколько улик раскрыто, сколько осталось. Это предотвращает «мы не знаем что делать» в асинхронном west marches, когда DM не за столом.


Зависимости

  1. spec-032 Encounter rework (роадмап 030+) — обязательный prereq. До него создавать node_type='quest' без encounter-as-node рискованно: придётся переделывать связи.
  2. spec-031 Карта — желательная prereq для quest → location рёбер.
  3. spec-033 DM Sandbox — квест в черновике должен быть скрыт от игроков до «выдачи»; это visibility-слой spec-033.

Номер спеки — 037 (роадмап 030+, NEXT.md).

npc-movement-and-encounters.md, near-term.md (позиция 037 в таблице).