Петля как ядро
Петля — центральная метафора проекта, не просто фича. Объясняет, что такое петля в нарративе, как она реализована в коде, и почему структура
(loop, day)пронизывает всю систему.
Mother of Learning — игра про прогрессию через циклы. Петля — это период игрового времени с фиксированным началом и условием сброса: мир возвращается к исходному состоянию, но персонажи сохраняют память, уровни и навыки. Нарративная механика новеллы Домогая стала архитектурной опорой инструмента.
Петля в нарративе
Группа проживает один цикл «реального» времени мира (в текущей кампании — 30 дней, хотя длина настраивается). В конце петли DM объявляет сброс: NPC забывают, данжи перезаполняются, некоторые последствия откатываются. Игроки несут с собой только то, что пережило сброс: уровни, абилки, часть золота, ключевые предметы. Пережить петлю значит стать лучше — это и есть прогрессия в progression fantasy.
Петля в коде
До миграции 012 петля жила в отдельной таблице loops. После — петля
стала нодой типа loop в общем графе (см.
node-graph.md).
Поля nodes.fields для петли:
| Поле | Тип | Смысл |
|---|---|---|
number | int | порядковый номер петли: 1, 2, 3… |
status | 'past' / 'current' / 'future' | активна ли петля |
length_days | int, дефолт 30 | длина в днях (миграция 032) |
Сессии — ноды типа session, связанные с петлей рёбром contains
(loop → session). Состав пачки — рёбра participated_in (session → character,
миграция 032).
Все транзакции несут (loop_number, day_in_loop) как временно́й якорь —
это позволяет фильтровать ленту бухгалтерии по петле, строить прогрессбар
и восстанавливать состояние «на конец дня N петли M».
Frontier — фронтир текущей петли
Прогрессбар петли (LoopProgressBar) рендерит ось от Day 1 до
loop.length_days. Каждая сессия с заполненными day_from/day_to ложится
сегментом на соответствующую дорожку. Если сессии перекрываются по дням,
алгоритм assignLanes (greedy) распределяет их по дополнительным рядам.
Для status='current' на баре рисуется фронтир — пунктирная вертикальная
линия после max(day_to) всех сессий с подписью «Дошли до дня N».
Это ответ на вопрос DM: «где сейчас группа в текущей петле?»
Сессии без day_from/day_to выводятся отдельным рядом пилюль ниже бара.
Сессия как диапазон дней
Сессия хранит day_from и day_to — это диапазон игровых дней,
которые охватывала встреча. Один реальный вечер может охватывать несколько
игровых дней (или меньше одного). Все транзакции, созданные в рамках сессии,
ссылаются на session_id, но их day_in_loop указывается явно — потому что
в рамках одной сессии разные события могут происходить в разные дни.
Связь с временно́й моделью
В проде сейчас: (loop_number, day_in_loop) — целые числа. Это грубая, но
работающая модель.
В целевой архитектуре (HANDOFF): (loop_id, at_tick), где at_tick —
целое от точки отсчёта кампании. loop_id — UUID, не порядковый номер.
Это нужно для точной временно́й сортировки событий внутри дня и для
ветвления петель (branch_id).
→ time-as-resource.md,
roadmap/tick-time-model.md
Прошлые петли read-only
Петли с status='past' доступны только для чтения. Лента событий прошлых
петель — хроника кампании; её нельзя редактировать (только через
DM-инструменты коррекции). Это база для future «time-travel UI» — просмотра
состояния мира на конкретный момент прошлой петли.
→
persistence-scope.md— что именно переживает сброс петли. →features/loops-and-sessions/README.md— как создавать петли и сессии в UI.