Engine pivot — миграция к движку с контент-паками

Карта инженерного pivot'а: от D&D-flavored MVP к универсальному RPG-движку. Это не одна спека — это порядок выполнения десятков спек, сгруппированных по зависимостям. Детали каждой опоры — в соответствующей статье этого раздела.

Текущий прод — рабочий инструмент для одной конкретной кампании, с жёстко захардкоженным D&D-контентом в схеме, без модель времени-пространства и без версионирования. Цель — движок, который не знает о Wizards of the Coast: D&D 5e изолируется в портабельный контент-пак, а ядро становится пригодным для любой west-marches кампании с петлёй.

Общая карта видения — north-star.md, §3–4. Глоссарий «в коде сейчас ↔ HANDOFF» — concepts/README.md.


Что уже в проде

До pivot'а в проде работают спеки 001–019, 023–029, 043–044, 046:

  • Граф нод+рёбер (спека 001) — фундамент хранения всех сущностей.
  • Транзакционный леджер transactions (спека 010) — деньги и предметы.
  • Общак, складчина, approval flow (011, 014, 017).
  • Каталог предметов + инвентарь v2 (015, 016, 018).
  • Encounter tracker v3 (002/005), чарник статблоки (007).
  • Self-hosted Supabase + CI/CD + staging (023–029, 043).
  • Telegram Mini App: мобильный кошелёк/бухгалтерия (044), auth + карточка PC (046).

Pivot начинается поверх работающего прода — не взамен. Каждая группа сохраняет обратную совместимость с предыдущими фичами.


Группа A — Фундамент

Что: универсальная таблица events, soft-delete, audit log, persistence scope.

Зачем: всё остальное — tick-время, NPC, visibility — пишет события в этот лог. Без этого фундамента нельзя корректно реализовать петлю времени.

ЗадачаСпека / ссылка
transactionsevents (добавить event_type, at_tick, visibility, persistence_scope, actor_id, location_id, payload, deleted_at)generic-events-table.md
event.deleted_at вместо hard DELETEaudit-log-and-safety.md
Таблица dm_audit_logaudit-log-and-safety.md
Версии контент-сущностей (item_version и т.д.)audit-log-and-safety.md

Зависимости: всё последующее. Группа A — блокер для B, C, D, E.


Группа B — Время и пространство

Что: tick-модель времени, типизированные локации, modifier stack.

Зачем: без at_tick нельзя ни корректно позиционировать NPC, ни считать стоимость перемещения, ни реализовать петлю с per-actor clock.

ЗадачаСпека / ссылка
(loop_number, day_in_loop)(loop_id, at_tick); tick_unit_seconds per-кампанияtick-time-model.md
Типизированные Location (hex/point/…) + Connection с base_traversal_tickslocations-hex-and-point.md — спека 031
ModifierStack, ActionCost.compute, WeatherResolver.at(tick), calendar configtime-and-modifiers.md

Зависимости: A завершена; B-элементы можно делать параллельно между собой, если не трогать production-данные без feature flag.


Группа C — Мир и активности

Что: NPC movement, encounter rework (designed + procedural), LocationSnapshot.

Зачем: когда есть тики и локации, DM может описывать намерения NPC, а движок знает, где кто находится на любой момент времени.

ЗадачаСпека / ссылка
NPCGroup с clock + MovementPlan + tick resolvernpc-movement-and-encounters.md
EncounterDefinition (designed) + EncounterTable (procedural weighted)npc-movement-and-encounters.md — спека 032
LocationSnapshot (append-only, observed_at_tick)locations-hex-and-point.md

Зависимости: B (нужны at_tick и Location).


Группа D — Мульти-юзер

Что: visibility + sandbox, west marches multi-DM, live broadcast, spectator.

Зачем: для открытой трансляции и управляемого тумана войны нужна таблица events с полем visibility и RLS-политика, которая его читает.

ЗадачаСпека / ссылка
event.visibility ({mode: 'all'/'dm_only'/'characters'}) + RLSvisibility-and-sandbox.md — спека 033
Роль spectator, participants.see_allvisibility-and-sandbox.md
DM session control: день/движение пачкиспека 035
Pack/PC movement timelineспека 036
West marches multi-DM конфигурацияwest-marches.md

Зависимости: A (нужен events + deleted_at); B желательна для 035/036.


Группа E — Контент-паки

Что: изоляция D&D-специфики из схемы в портабельный JSON-формат content_pack.

Зачем: сделать движок независимым от конкретной игровой системы и дать возможность переносить персонажей между кампаниями.

Машинерия паков строится в эпике «RPG-движок» — спеки 045–051 (Engine Core → спеллы → форк → фиты → пирамида → классы → конструктор). Спека 045 Engine Core — ближайший элемент этой группы.

ЗадачаСпека / ссылка
Движок: модули, эффекты, ресурсы (слой-0, прозрачность, реалтайм)спека 045
Формат pack: JSON Schema, версии, импорт/экспортcontent-packs.md
База спеллов (машинерия баз dnd.su)спека 046
Форк нод (forked_from, хоумбрю)спека 047
База фитов + бэкграундовспека 048
Пирамида прогрессии (level-up)спека 049
База классов / мана-максимум (DMG Spell Points)спека 050
Конструктор хоумбрю (effect-блоки)спека 051

Зависимости: A (нужен events); желательны B и C.


Параллелизм и freeze-окна

Группы A и E (Engine Core, спека 045) можно начинать независимо — 045 не трогает существующий транзакционный слой. Внутри группы B элементы параллелятся при условии feature flags. Миграция времени (B: at_tick) — единственное место, где потребуется согласованный freeze production-данных: старые (loop_number, day_in_loop) должны быть конвертированы атомарно.

Не требуют freeze: группы C, D, E (добавляются новые таблицы поверх существующих).


Связи с другими разделами