North star — куда движется проект
Долгосрочное видение проекта. Этот документ — не описание текущего прода, а карта направления, в котором проект движется. Текущая реализация описана в разделе
features/; разрыв между «сейчас» и «целью» расписан вroadmap/engine-pivot.md.
1. Что это за проект
Mother of Learning — это веб-приложение, ассистент для ведения сложных ролевых кампаний в формате west marches с множеством DM и игроков, петлёй времени и асинхронным игровым временем. Назван по веб-новелле Домогая, для кампании по которой инструмент изначально и создавался.
Формат целевой кампании
- West marches. Один общий мир. Игроки собираются ad-hoc в пачки, несколько DM ведут параллельно. Никакой жёсткой посадки за стол по расписанию — кто свободен сегодня, тот и играет.
- 30+ игроков, у каждого может быть несколько персонажей.
- Петля времени как мета-механика: периодический сброс мира с сохранением памяти персонажей. Нарративная сердцевина новеллы и одновременно опора архитектуры.
- Асинхронное игровое время. У каждого персонажа свой «сейчас». Один игрок ведёт PC через данж в день 5; другой в это же время оффлайн делает закупки в городе в день 12. Реальное время — общее, игровое — индивидуальное.
- Параллельные оффлайн-активности. Между сессиями — даунтайм, путешествия, личные квесты в одиночку. Всё это надо учитывать, не теряя.
- Live broadcast и интерактивный лог. Кампания разворачивается на глазах у зрителей. Лог рассказывает историю каждой петли.
Что приложение делает
- Отслеживает асинхронное время каждого персонажа.
- Хранит лог всех событий мира с возможностью восстановить состояние на любой момент.
- Управляет состоянием локаций, NPC, энкаунтеров с учётом времени, погоды, террейна.
- Даёт DM полный контроль над миром (см. DM как полный демиург).
- Подсказывает процедурно — содержимое новых локаций, таблицы случайных встреч (DM принимает / отклоняет).
- Реализует петли времени технически — через event sourcing с persistence scope.
- Транслирует поток событий зрителям и игрокам в реальном времени.
Долгосрочная цель
- Open source. Бесплатно для всех.
- Универсальный инструмент для west-marches и схожих сложных кампаний — не только под одну книгу.
- Контент-паки портабельны между кампаниями. В перспективе — мост
между мирами с разными правилами, перенос персонажей с проверкой
совместимости (см.
roadmap/content-packs.md). - D&D-специфика изолирована от движка. Ядро ничего не знает о Wizards of the Coast (см. Движок vs контент).
2. Концептуальные принципы
Пять опор, на которых стоит проект. Каждая раскрывается в собственной статье; ниже — короткая свёртка.
Tool-first, simulation-second
Главный принцип. Mother of Learning — инструмент для DM и игроков,
не симулятор мира. Симуляция возникает там, где снимает с DM
рутину (бросить кубик, посчитать стоимость в тиках). Симуляция не
возникает там, где ограничивает DM (автономные NPC с собственной
волей, мир, который «идёт сам»). Любое автоматическое поведение
мира — либо опциональное, либо легко переопределяемое DM.
→ tool-first.md
Время как первоклассный ресурс
«Вся игра про время. Про то, как время утекает.»
Время — главный ресурс игры наравне с HP, MP, деньгами. Каждое
действие имеет явную стоимость (в тиках в целевой модели; в днях
сейчас). Каждый модификатор — погода, террейн, время суток, режим
перемещения, кондишены — явно влияет на эту стоимость. UI показывает
игроку временную цену до того, как он принимает решение.
→ time-as-resource.md
DM как полный демиург
DM может что угодно. Удалить, добавить, поменять. Без guardrails,
кроме физических защит данных. Все DM-операции — события; RLS
разрешает role=dm писать любые типы событий. Safety обеспечивается
через soft delete, версионирование контента и audit log — но не
через ограничение прав.
→ dm-as-demiurge.md
Мир как лог наблюдений
До наблюдения мира нет. DM держит планы в голове или в личном
scratchpad'е, но в БД ничего не отражено до момента, когда игрок
реально приходит в локацию. Единственное, что фиксируется —
состояние локации в момент наблюдения. Это упрощение по сравнению
с Dwarf-Fortress-моделью, где мир существует параллельно игроку и
живёт сам.
→ world-as-observation-log.md
Открытая видимость по умолчанию
Day 1: все события видят все игроки и зрители. Игроки кооперируются,
делятся информацией, DM пишет подробные рекапы. Скрытые действия
(туман войны, стелс) поддержаны в схеме (event.visibility), но UI
для них появится позже. Архитектура финальная сразу — миграции схемы
не потребуется.
→ visibility.md
3. Архитектурные опоры
Восемь конкретных решений, на которых стоит целевая система. Каждое —
отдельная инженерная работа в roadmap/. Ниже — краткое описание;
детали и порядок миграции — в
roadmap/engine-pivot.md.
Тики — базовая единица времени
Campaign.tick_unit_seconds задаётся per-кампания (для основной —
6 секунд, один раунд боёвки D&D 5e). Время в БД хранится как
at_tick: int от точки отсчёта кампании — целое число, не datetime,
не «Day N, Hour H». Конвертация в человекочитаемое представление —
presentation layer. У каждого персонажа свой current_tick. Длинные
действия («тренируюсь магии 3 месяца») — один event с start_tick и
duration_ticks, а не итерация миллиона тиков.
→ roadmap/tick-time-model.md
Persistence scope — петля времени
Каждое событие имеет тег: loop (мир, инвентарь, сюжет — сбрасывается
при reset петли), character (память персонажа, уровни, навыки —
сохраняется), meta (мета-сюжет, NPC-память «кто-то помнит» —
сохраняется). Loop reset = создание нового loop_id. При свёртке
мира фильтр оставляет только текущий loop + character/meta. Поле
branch_id с дефолтом 'main' зашит в схему сразу, на старте не
используется — задел под ветвление петель в будущем.
→ persistence-scope.md
Универсальный лог событий
Append-only таблица events со столбцами event_type, at_tick,
actor_id, location_id, payload jsonb, visibility,
persistence_scope, deleted_at. Это фундамент. Все DM-операции,
действия игроков, движение NPC, изменения погоды — события. Текущая
таблица transactions (только money/items) — частный случай этого
лога; в pivot'e она расширяется до универсального вида.
→ event-sourcing.md, roadmap/generic-events-table.md
Локации: hex + point + иерархия
Абстрактный Location с type: 'hex' | 'point' | 'street' | 'dungeon_room' | ... и иерархией через parent_location_id.
Отдельная таблица Connection хранит рёбра с base_traversal_ticks,
направлением, типом террейна, флагом hidden. На старте — два
типа: hex (wilderness, 6 направлений, hex-математика) и point
(города, регионы, данжи с явным графом). Уровни сосуществуют:
глобальная hex-карта мира → внутри гекса pointcrawl поселения →
внутри точки depthcrawl данжа.
→ roadmap/locations-hex-and-point.md
Encounters: designed + procedural
Гибридная модель. EncounterDefinition — спроектированные встречи,
прибитые к локации; основа петли: игрок встречает то же самое в той
же локации, потому что петля. Если DM позволяет — пропуск автобоем,
когда игроки уже знают решение. EncounterTable — процедурные
таблицы: weighted entries с модификаторами по времени суток и
погоде. Используется как подсказки DM при заполнении новых локаций
и как источник wandering encounters.
→ roadmap/npc-movement-and-encounters.md
Modifier stack, weather, calendar
Стоимость любого действия = base_cost × stack_of_modifiers. Стек
применяется детерминированно в фиксированном порядке: terrain ×
weather × time-of-day × travel-mode × condition. UI показывает
разложенную цену игроку: «Перемещение в C: 800 тиков (база 600
× болото 1.2 × дождь 1.1)» — игрок видит факторы и принимает
осознанные решения. Calendar и weather — глобальное состояние
кампании, DM перебивает в любой момент. Weather — manual /
procedural / hybrid с детерминированным сидом.
→ roadmap/time-and-modifiers.md
NPC tracking — бухгалтерия движения, не AI
DM заявляет намерение, система тикает, игроки видят туман войны.
NPCGroup со своим current_tick и movement_plan (маршрут как
список локаций с dwell-ticks). На каждый tick advance resolver
пересчитывает позиции с учётом модификаторов; пересечения с активным
игроком → encounter check. DM видит активные планы в дашборде,
может остановить / изменить / удалить. Это не «мир живёт сам» —
это запланированное движение под надзором.
→ roadmap/npc-movement-and-encounters.md
Видимость и live broadcast
Поле event.visibility JSONB трёх форм: {mode: 'all'},
{mode: 'dm_only'}, {mode: 'characters', character_ids: [...]}.
RLS-политика проверяет это поле. Spectator — это participant без
controlled-characters; видит то же, что игроки (mode='all').
Опциональный participants.see_all: bool даёт расширенный доступ
(для соведущих, ассистентов). Партии — UI-агрегация, не
security-граница.
→ visibility.md, roadmap/live-broadcast.md
Audit log + soft delete + версии контента
Safety layer для DM-as-demiurge. Вместо ограничения прав — следы.
event.deleted_at nullable вместо DELETE. Каждая content-сущность
с version: int; правка создаёт новую версию, старые остаются;
события ссылаются на конкретную версию. Отдельная таблица
dm_audit_log пишет каждую DM-операцию (action_type, target_id,
before_state, after_state, timestamp). Что DM не может: уронить
базу, удалить чужую кампанию, писать в auth.users.
→ roadmap/audit-log-and-safety.md
4. Где мы сейчас vs north star
Текущий прод — D&D-flavored MVP для одной конкретной кампании,
с одним выделенным DM (хотя несколько dm-аккаунтов уже могут
сосуществовать). Большая часть архитектурных опор пока отсутствует
или представлена урезанной версией. Кратко:
| Опора | В проде сейчас | Целевая модель |
|---|---|---|
| Время | (loop_number, day_in_loop) целые числа | (loop_id, at_tick) с tick_unit_seconds |
| Лог событий | transactions (только money/items) | универсальный events с persistence/visibility |
| Локации | обычные ноды в графе | типизированные Location + Connection |
| Encounters | ручной грид per session | designed + procedural таблицы |
| Modifier stack | нет (DM считает в голове) | детерминированный стек, разложенный UI |
| Weather, calendar | нет | manual / procedural / hybrid resolver |
| NPC movement | нет (NPC стоят там, где стоят) | MovementPlan + tick resolver |
| Видимость | нет (всё открыто) | event.visibility + RLS |
| Audit log + soft delete | нет | dm_audit_log + deleted_at everywhere |
| D&D vs движок | переплетены | content-packs изолируют D&D |
Полная карта миграции — в
roadmap/engine-pivot.md. Глоссарий
«название в HANDOFF ↔ название в коде сейчас» — в
README.md этого раздела.
5. Что не делаем сейчас
Сознательно отложено до того, как ядро устаканится:
- Solo / co-op / MMO режимы (см. ниже «фантазии»).
- Branching петель (поле
branch_idесть, использования нет). - Полноценный туман войны / hidden actions UI (поле
visibilityесть, UI нет). - Продвинутые кроулы — streetcrawl, depthcrawl.
- Travel modes сверх Normal / Cautious.
- Импорт существующей БД D&D — пока минимальный hardcoded набор для
тестов (см.
features/inventory-and-items/technical.md). - Production-grade арт. Прототипируем на квадратах и схемах.
6. Что когда-нибудь может быть
То, что может появиться позже, но сейчас не входит в скоуп.
Эти штуки — за горизонтом инженерного pivot'а из
roadmap/engine-pivot.md.
Мульти-режимность
Расширение классического DM-driven workflow до:
- Co-op — игроки против мира, без живого DM, мир по жёстким правилам.
- Solo — один игрок, мир реагирует через автоматического DM.
- MMO-элементы — пул world-DM'ов, общий мир для многих кампаний.
В этих режимах система играет роль DM по жёстким правилам — частный случай инструмента, не основное назначение.
Метавселенная RPG-инструментов
- Контент-паки портабельны между кампаниями.
- Мост между мирами с разными house rules.
- Перенос персонажей с проверкой совместимости пакетов.
Игровой клиент на Godot
Полноценный desktop / мобильный / web клиент с богатой
визуализацией: гекс-карты с анимациями перемещения, сцены боя,
реалтайм-визуализация чужих перемещений, богатый UI для просмотра
лога и трансляции. Подпроект godot/ с собственной слоёной
архитектурой (core/content/presentation/networking), подключается
к той же Supabase-БД через репозитории. TS-фронт остаётся как
админка / DM-инструмент / редактор контента.
Важно: до того момента, как Godot-клиент станет реальным проектом, никакая Godot-специфика не должна влиять на схему БД или дизайн API.
Branching петель
DM временно ветвит мир для эксперимента («что если бы группа
выбрала другое»), потом merge или discard. Поле branch_id уже
есть, миграция простая.
Продвинутая видимость
Полноценный туман войны — скрытые действия и стелс, тихие запросы к
DM, информация распространяется через событие knowledge_shared
между персонажами. Поле visibility уже поддерживает это, нужен
только UI.
Процедурные тулзы для DM
Таблицы по биомам с весами, генерация структуры данжей, AI-ассистированные подсказки по сюжетным линиям. Это всегда suggestion, не автоматическое действие.
7. Открытые архитектурные вопросы
Не блокеры, но ответы повлияют на дальнейшие решения:
- Edge Functions vs Postgres functions для бизнес-логики DM на сервере. Postgres-функции проще, Edge Functions гибче. Для прототипа — Postgres-функции и триггеры.
- Реалтайм-стабильность. Supabase Realtime иногда отваливается. Нужна продуманная стратегия reconnect + state resync. Решение к моменту первого многопользовательского теста.
- Content-pack формат. JSON, JSON Schema, версионирование, импорт / экспорт. Нужен до того, как накопится много контента.
- Импорт существующих D&D данных. Есть сторонняя БД с
предметами / монстрами / локациями. Способ импорта — отдельная
задача (частично закрыта в проде, см.
features/inventory-and-items/technical.md).
8. Источники вдохновения
Game design / RPG theory
- The Alexandrian — thealexandrian.net, в частности Remixing Avernus. Многоуровневые карты (hex/point/streetcrawl), процедурные энкаунтеры, watch-структура времени, off-camera encounters, Three Clue Rule, node-based scenario design, holographic goals для west marches. Прочитать обязательно перед серьёзной работой над архитектурой контентных слоёв.
- Веб-новелла Домогая — петля времени как мета-механика, для которой инструмент изначально и создавался.
- West marches в оригинальном Ben-Robbins-стиле — ad-hoc пачки, общий мир, DM как ситуационный, не привязанный к расписанию.
Концептуальные параллели в индустрии
- Crusader Kings III — асинхронное время, события на каждого актора, AI-генерация ситуаций, которые игра подбрасывает игроку.
- Dwarf Fortress — сложный мир, который существует параллельно игроку. Mother of Learning отличается принципиально: мир не существует без наблюдения. Это упрощение.
- Roll20 / Foundry VTT — конкуренты по DM-tooling, но они синхронные (все за столом одновременно). Mother of Learning — асинхронный, это ключевое отличие.
- Disco Elysium — UI-вдохновение для богатого текстового слоя, лога действий, рассказывающего историю.
Этот документ обновляется после ключевых решений. Если что-то здесь расходится с реальностью кода больше чем на квартал — пора либо обновить документ, либо обсудить, не пора ли подвинуть код.