Статус: маршрут, составлен 2026-08-01 по списку Макса. Порядок выбран Максом в тот же день: сетевой трек первым, вместе с билдом и деплоем в Steam (§5). Рекомендация скрайба сохранена рядом — она объясняет зависимости внутри основного трека.
Зачем этот документ. Список Макса пересекает пять существующих планов (Тех: Roadmap, ГД: Roadmap, Coop Vertical,
docs/ui-architecture-rework-plan.md, Техдолг) и ни в один не помещается целиком. Здесь — маршрутизатор: что из списка уже есть в коде, куда каждый пункт ложится и в каком порядке имеет смысл идти. Своих дизайн-решений документ не вводит: всё, что требует вердикта, вынесено в §7.
1. Список Макса (2026-08-01) — его формулировки
Пять блоков, дословно по сути (сокращения многоточием, порядок его):
- Баланс забега. «Можем как-то для баланса считывать “забег”? … Сколько чего встретилось на пути. Как это повлияло на винрейт (надо отдельно еще продумать как прогонять весь забег, просчитать что игрок должен получать в среднем и в каком количестве, посчитать баланс врагов, подумать как должны работать бои? нельзя же бой что встретит сразу и почти в конце делать одинаковым для выпадения?)»
- Недостающий UI, предметы, инфа об юните. Хаб гильдии (кнопки «начать забег» и неактивная «метапрогрессия»), редактор создания гильдии, меню профилей и сейвов; экран начала забега (выбор Капитана, выбор Экипажа, скилл Капитана на дополнительном этаже); UI инвентаря, «актуальные тултипы для контента, актуальные описания, возможность их приемки удобной»; третий раздел Отряд (убирать «Сосуд» с поля, выставлять юнитов драгом, задел под наёмников); «UI получения награды вообще ужас»; «завести норм экономику — и мета, и валюта в забеге, и валюта коопа на будущее»; нормальные награды валюты после боя, нормальный магазин; «наконец сделать забег где доступны НЕ сразу все релики, а реальный забег (2 треша + 1 активка на выбор при старте, после взятия бонуса)».
- Мультиплеер до играбельного тестового состояния. Кнопка «сетевая игра» → окно «создать / присоединиться»; временный режим «расставляемся против пачки мобов»; PvP «ибо это вроде как дешево» — расстановка друг против друга, чужую расстановку не видно, оба жмут «готов» (гейт готовности нужен и PvE, и PvP).
- Подготовка к билду. Потом от Макса — «посмотреть все экраны, причесать»; настроить пайплайн деплоя в Steam.
- Внешний вид UI. «У нас очень красивый сплеш в начале. очень классное меню. Но вот реальные кнопки в игре, реальный внешний вид UI — я понимаю, что слабый, надо с этим что-то придумать.»
2. Инвентарь: что из этого уже стоит в коде
Проверено по дереву 2026-08-01. Колонка «годность» — можно ли на это опереться, не переписывая.
| Что | Где | Годность |
|---|---|---|
| Петля забега целиком | Game/Flow/ — RunFlow, BattleNodeFlow, ShopFlow, CampFlow, ChestFlow, TextEventFlow, RandomEventFlow | работает; узлы полиморфны через IEventFlow |
| Карта акта из сида | Guild/MapGenerator + MapGenConfig | работает, детерминирована |
| Экраны на UXML | UI/Screens/ — 19 файлов, включая RewardScreen, ShopScreen, EventScreen, OutcomeScreen, MainMenuScreen, TitleCardScreen, PauseScreen, SettingsScreen | разметка есть; сборка экранов живёт в MenuRouter.cs (1131 строка) |
| Навигатор UI | UI/Navigation/ — UiNavigator, UiScreen, ScreenKind; зарегистрирован в RootLifetimeScope | Ф1–Ф2 реворка сделаны: роутер делегирует навигатору видимость и глушение |
| Слои корня | UiRootBootstrap + TooltipSystem (layer-*) | заведены |
| Тултипы | UI/Tooltips/, UI/Components/TooltipCard | система есть; Descriptor-слой (числа и описания) — нет |
| Профиль и дом | Guild/ProfileState.cs — ProfileState (открытия игрока) и GuildState (казна, ростер 8→64, возвышение) | модель данных есть, экранов нет |
| Сейвы | ISaveService → JsonFileSaveService, конверты, SaveLoadResult<T> | работает; экрана выбора профиля/слота нет |
| Награда за бой | RunStateService.AwardBattleReward → GameConfig.BattleGoldReward | плоская константа 20 независимо от тира и состава |
| Витрина мементо | Game/Flow/RewardService — ramp 10 / 20 / 100 % по RewardTier | работает |
GoldBounty у врагов | Data/Definitions/EnemyData.cs:30 | поле есть, не читается никем |
| Пул мементо в лоадауте | UI/LoadoutViewModel.cs:50 — _content.All<RelicData>() | все 27 доступны сразу — ровно то, что Макс просит убрать |
| Лог команд забега | Guild/Commands/ — шина, лог, применитель | сделан 01.08; новые экраны обязаны писать в RunState только через него |
| Сетевые швы | Net/Transport/ (интерфейс, loopback, chaos), Net/Presence/ (курсоры), Data/ContentFingerprint | фазы А и В коопа закрыты, кроме отрисовки курсора и UTP-профиля |
| Гейт готовности | Game/Flow/RunFlowSeams.cs — IReadyGate + SoloReadyGate | шов есть, сетевого тела нет |
| Steam | Net/FacepunchTransportBootstrap.cs, AppId 3259720 (чужой слот, до демки) | инициализация есть, лобби нет |
| Балансный стенд | Scripts/Balance/Editor/ — SimBench, бенчи, нормы, отчёты | меряет бои, не забеги |
| CI-сборка | .github/workflows/ci.yml — build на StandaloneWindows64, только PR и master | отвечает «собирается ли», артефакт не публикуется |
Контент на диске: 27 мементо, 19 врагов, 108 эффектов, 3 предмета.
3. Разбор блоков: что за пунктом на самом деле
3.1 Баланс забега (блок 1) — задача расщепляется надвое, и половина блокирована
Пункт читается как «сделать тулинг», но внутри две разные работы.
(а) Дизайн — есть сейчас и ничем не блокирован. Прежде чем что-то мерить, нужны нормы забега, которых у нас нет ни в одном доме:
- бюджет энкаунтера и кривая по этажам — «нельзя же бой в начале и почти в конце делать одинаковым». Тема уже стоит без вердикта: ГД: Roadmap Блок 2, «Ориентир сложности» (числовой показатель силы энкаунтера в духе Recommended Value из Legion TD 2);
- таблица наград по типам узлов — сколько золота, мементо и предметов игрок получает в среднем
за акт. Сейчас золото за бой плоское (20),
GoldBountyмёртв, дизайн-дом ГД: Мета-прогрессия и экономика описывает ramp редкости, но не темп денег; - что считать нормой забега — по правилу «сначала норма, потом замер» (память
balance-norm-before-measure) без неё прогон даст числа без вердикта.
(б) Тулинг — run-sim поверх SimBench. Технически это прямое продолжение стенда: SimEnvironment
уже умеет прогонять бой headless, MapGenerator — катать карту из сида. Не хватает верхнего цикла
«карта → узлы → награды → следующий бой» и метрик забега (что встретилось, что взято, где умер).
Почему (б) нельзя делать первым. Прогон измерит генератор наград, которого нет, и драфт, которого нет: сейчас игрок берёт любую из 27 мементо сразу, деньги плоские, врагов на весь акт девятнадцать и BAL-015 уже говорит, что энкаунтеры не спрашивают ничего. Run-sim в таком состоянии измерит заглушки.
Вывод: (а) — сейчас, (б) — после того, как заработает «реальный забег» из блока 2.
3.2 Реальный забег (внутри блока 2) — это фундамент, а не последний пункт
Макс поставил его последним в блоке, но от него зависят три других: экономика, награда, магазин — и весь блок 1. Состав работы:
- Стартовый драфт: 2 треша + 1 активка на выбор при старте (после взятия бонуса), вместо
All<RelicData>(). Требует пула доступного в забеге и правил его пополнения. - Экономика в трёх кошельках (валюта дома · золото забега · личная валюта коопа) — третий уже
объявлен решением 01.08 (журнал «The Ruler Gets A Third Currency»); в коде золото забега живёт в
RunState, казна дома — вGuildState, личной нет. - Награда за победу как функция от боя, а не константа: тир узла, состав врагов,
GoldBounty. - Магазин: ассортимент, цены, реролл.
ShopControllerиRelicPricerесть, дизайн цен — нет.
Дизайн-дом всего этого — ГД: Мета-прогрессия и экономика; правки в неё
идут через gdd-scribe, числа — через balance.
3.3 Экраны (блок 2) — порядок задан не важностью, а зависимостями
Шесть новых экранов: профили и сейвы · хаб гильдии · создание гильдии · старт забега (Капитан + Экипаж) · Отряд · переделка награды.
Три замечания, которые меняют порядок:
- UI-реворк доведён до Ф2 (из семи). Навигатор подключён, но сборка экранов по-прежнему живёт в
MenuRouter.cs(1131 строка), Ф3 (ShowAsyncвместо Detach-резолвов) и Ф4 (слои вместоBringToFront) не закрыты. Шесть новых экранов, положенных на роутер в этом состоянии, удвоят работу по Ф3–Ф4. Ф3–Ф4 идут перед новыми экранами. - «Актуальные тултипы и описания» — это не тултипы, а Трек С + Трек Д-о. По плану UI-реворка
число, показанное игроку, обязано приходить из того же калькулятора, что у симуляции
(
Stats.Explain(StatType) → StatValue), а описания — из Smart Strings с падежами RU. Без этого панель юнита и карточка в инвентаре станут вторым, тихо расходящимся с балансом экземпляром правил. Трек С помечен в плане как «делать РАНО» — он и правда идёт перед экраном Отряда. - «Инфа об юните» уже спроектирована как Трек П: нижний бар партии + панель юнита по ПКМ, оба persistent-слоями, не тултипами.
3.4 Мультиплеер (блок 3) — половина вертикали уже стоит
По Coop Vertical: фаза А закрыта (лог команд, транспорт за интерфейсом, chaos, отпечаток контента), фаза В закрыта кроме отрисовки курсора. Остаются:
- фаза Б — кодек чанка боевой ленты, раздача и склейка;
- фаза Г — сессия: лобби, инвайт, дисконнект, «хост ушёл = конец сессии».
Кнопка «сетевая игра» с окном «создать / присоединиться» — это и есть фаза Г плюс один экран.
PvP «дешево» — с оговоркой. Дёшево то, что симуляция уже команда против команды, лента уже
раздаётся чанками, а IReadyGate — заложенный шов. Не дёшево: скрытие чужой расстановки (сейчас
расстановка не приватна ни на каком уровне), правила режима (кто выиграл, что дальше) и экран лобби.
Оценка честная: PvP-спарринг дешевле полного коопа забега, но дороже, чем «кнопка» — и он не
требует ни экономики, ни петли забега, поэтому годится как независимый трек.
3.5 Билд и Steam (блок 4)
- Билд уже собирается в CI (
build, StandaloneWindows64, Linux-раннер, Mono). Чего нет: публикации артефакта и регулярного запускаемого билда на руках. - Деплой в Steam упирается в свой AppId. Тесты идут на слоте неизданной Few Seconds - Many
Deaths! (3259720); свой слот решено покупать ближе к демке (Coop Vertical §2.1). Пайплайн
(
steamcmd+ депоты + веткаbeta) настраивается за вечер, но без своего слота его некуда направить. - «Посмотреть все экраны и причесать» по определению идёт после того, как экраны есть.
3.6 Внешний вид UI (блок 5) — не «отдельно потом», а до штамповки экранов
Это единственный пункт, который я предлагаю поднять, а не опустить. Причина механическая: шесть новых экранов будут нарисованы в том же языке, что нынешние. Если язык менять после — перерисовывать придётся дважды.
Что под этим лежит: реф-база уже собрана (Art_Dev/UI Refs/, с методикой teardown), дизайн-система
токенов работает для цвета, но semantic-яруса нет для spacing / border / font / radius — их
потребляют примитивами напрямую в десятках мест (Трек Д плана реворка). То есть «слабый внешний вид»
имеет конкретную техническую причину, а не только вкусовую.
Форма работы, которую предлагаю: один эталонный экран (кандидат — награда, её Макс сам назвал худшей) прорабатывается визуально до конца, из него вынимаются недостающие токены и базовые классы 9-slice, и уже этот словарь применяется к остальным.
4. Чего в списке нет, а стоило бы
Не претендую на переопределение приоритетов — это то, что всплыло при сверке и дёшево закрыть.
| Что | Почему это заметно | Дом |
|---|---|---|
Флоу падает в Quit при ошибке | любая необработанная ошибка петли забега роняет игру вместо экрана «забег прерван» | план реворка II.12.4 |
| Бут-экран не закрывается с геймпада | NavigationSubmitEvent не обрабатывается нигде в проекте — игрок с геймпадом застревает на первом экране | Техдолг §3.20 |
| У скелетного рига нет клипа смерти | в слоте Death стоит Idle — юнит перед распадом стоит в позе покоя; видно в игре | Техдолг §3.11 |
| Гейт полноты лок-ключей | docs/loc-missing-keys.md живёт вручную; к билду нужен автоматический | — |
| Контент врагов | BAL-015: элиту проходит отряд без кита; заход «все враги» начат (docs/enemies-implementation-progress.md) и не закончен | balance + content-design |
5. Порядок — ВЕРДИКТ МАКСА 2026-08-01: сеть первой
Сказано: «Если все записала - то хорошо. Я бы хотел мультиплеер PvP и PvE, билд и закидон его в Steam с пайплайном для начало. Очень хочу протестировать что в коопе все норм работает, хихи.» (2026-08-01, сессия c3712a93).
Порядок принят такой: сетевой трек идёт первым и целиком, вместе с билдом и деплоем в Steam; основной трек (экономика, забег, экраны) ждёт. Рекомендация скрайба ниже сохранена как есть — она объясняет зависимости внутри основного трека, и её порядок остаётся в силе внутри него.
Что это значит для §3.1 и §3.2: run-sim и «реальный забег» отодвигаются, поэтому баланс забега меряться пока не будет — это осознанная цена за раннюю проверку коопа вживую.
Вставка 2026-08-02: перед С3 идёт разделение скоупов
Решено Максом 02.08.2026: сетевой трек прерывается на заходе по иерархии уровней (Planning - Scope Hierarchy). Причина не в сети: у боевого скоупа нет границы боя, поэтому её объявляют вручную, и каждый новый участник обязан подписаться — кто не подписался, ломается молча. Роль коопа жить в такой форме не может, и PvP из С3 некуда класть: он отдельный вид Занятия, а не вариация Забега.
Сеть продолжается после фазы 2 плана (Мир → Бой → Сессия): там роль уже готова и композиция собирается по ней. Формулировка: «все что работает не так - выдергиваем с корнем, никакого легаси!»
Порядок работ сетевого трека (детализация С1–С3 под вердикт)
| Шаг | Что | Готово, когда |
|---|---|---|
| С1 | кодек чанка боевой ленты, раздача и склейка (фаза Б плана коопа) | роундтрип побайтово совпал; два клиента на loopback проиграли один бой одинаково |
| С2 | UTP-профиль + сессия: экран «Сетевая игра» (создать / присоединиться), Steam-лобби и инвайт, дисконнект, «хост ушёл» | двое соединились и смотрят один бой |
| С3 | режимы-спарринги: PvE «против пачки мобов» и PvP с приватной расстановкой; общий гейт «готов» на оба | вдвоём проходится и то, и другое |
| С4 | курсоры на экране (присутствие уже готово ниже отрисовки) | видно курсор напарника |
| С5 | билд и Steam: публикуемый артефакт из CI, steamcmd-пайплайн, заливка в закрытую ветку | билд ставится из Steam и в нём играется кооп |
Развилка, вскрытая вердиктом: деплой в Steam упирается в слот. Тесты идут на AppId 3259720 (неизданная Few Seconds - Many Deaths!), и заливать туда депот ради проверки пайплайна технически можно, но это чужая страница игры. Варианты — свой слот сейчас (деньги плюс модерация) или пайплайн на старом слоте с переездом одним числом позже. Решается до С5, не раньше.
Рекомендация скрайба (составлена до вердикта, порядок внутри основного трека в силе)
Два трека, которые почти не пересекаются по файлам и потому могут идти параллельными сессиями:
основной (контент, экономика, UI) и сетевой (Net/, Guild/Commands/, один экран лобби).
Основной трек
| Шаг | Что | Почему здесь |
|---|---|---|
| 0 | fail-safe флоу · бут-экран (геймпад, звук, три лок-ключа) · клип смерти рига | часы работы, а ломается это на первом же показе |
| 1 | дизайн-заход «экономика и кривая забега»: бюджет энкаунтера по этажам, таблица наград, три кошелька, цены магазина, правила стартового драфта | разблокирует всё остальное; чистый спарринг, кода не требует |
| 2 | реальный забег в коде: стартовый драфт 2+1, награда как функция боя, GoldBounty, магазин по ценам | после этого игра впервые «забег», а не песочница |
| 3 | UI-фундамент: Ф3–Ф4 реворка · Трек С (Stats.Explain) · визуальный язык на эталонном экране (награда) | три вещи, ретрофит которых стоит переписывания экранов |
| 4 | экраны по зависимостям: профили и сейвы → хаб гильдии → создание гильдии → старт забега (Капитан + Экипаж) → Отряд → магазин и награда в новом языке | каждый следующий опирается на предыдущий |
| 5 | Трек Д-о + Трек Т + Трек П: описания, тултипы, панель юнита и бар партии | «инфа об юните» из блока 2, требует шага 3 |
| 6 | run-sim и баланс забега (блок 1б): верхний цикл поверх SimBench, метрики забега, отчёты | меряет уже настоящую петлю |
| 7 | билд-гейт и Steam: публикуемый артефакт, свой AppId, steamcmd-пайплайн, проход Макса по экранам | последнее по определению |
Сетевой трек (параллельно, с шага 1)
| Шаг | Что |
|---|---|
| С1 | фаза Б: кодек чанка ленты, раздача, склейка, переписать NetworkCommandRelay под Pause/Resume |
| С2 | фаза Г: лобби, инвайт, дисконнект, «хост ушёл»; UTP-профиль; отрисовка курсора |
| С3 | режим-спарринг: PvE «против пачки мобов» и PvP с приватной расстановкой, общий гейт «готов» |
Главные расхождения с порядком Макса, чтобы они не потерялись:
- «Реальный забег» поднят с конца блока 2 в начало — от него зависят награды, магазин, экономика и весь блок 1.
- Блок 5 (внешний вид) поднят к UI-фундаменту — иначе шесть экранов рисуются дважды.
- Блок 1 (баланс забега) опущен ниже экономики — иначе он измерит заглушки.
- Блок 3 (мультиплеер) вынесен в параллельный трек, а не в очередь: он не конкурирует за файлы с основным и не зависит от экономики.
6. Правила, которые действуют на всю эту работу
- Запись в
RunState— только через шину команд (IRunCommands). Новый экран, дёрнувшийRunStateServiceнапрямую, — дефект, а не срезка (Coop Vertical §4.1). - Число, показанное игроку, не вычисляется кодом UI — только из калькулятора симуляции.
- Лок-ключи закладываются сразу, включая формы падежей у keyword.
- Навигация client-local и не реплицируется — у каждого игрока своё «какое окно открыто».
- Новый UI — из дизайн-системы: токены и готовые компоненты, своё — исключение с обоснованием.
7. Что требует вердикта Макса
- Порядок §5 — принять, переставить или отвергнуть.
- Кривая сложности энкаунтера: числовой ориентир силы (видимый игроку, как Recommended Value) — вводим или нет; и как считается бюджет боя по этажам.
- Темп денег за акт: сколько золота игрок получает в среднем и на что его хватает.
- Стартовый драфт: «2 треша + 1 активка» — это выбор из скольких, и что за «бонус», после взятия которого он происходит.
- Личная валюта коопа: заводим сейчас как поле или откладываем до транзакций.
- Свой Steam AppId: покупаем сейчас (деплой-пайплайн настраивается на настоящем слоте) или ближе к демке, как решено 01.08.
- Эталонный экран для визуального языка: награда — или другой.