31 KiB
Vanguard ReMaster — состояние сессии
Дата: 2026-10-24
HEAD: см. git log -1
Коротко: сервер готов, клиент — рабочий каркас с 3D-сценами.
Правила работы
- Ответы короткие, без повторов и длинных вступлений — экономия токенов.
- Любое сомнение/вопрос — диалог: 2–4 варианта с рекомендацией, выбор за пользователем (или его свободный ответ). Не угадывать.
- Полный свод правил —
AGENTS.md. - Новые изменения: анализ DeepSeek → план в
docs/Development/IMPLEMENTATION_PLAN.md→ реализация Kimi. Код на этапе анализа не меняется; процесс —docs/Development/AGENT-WORKFLOW.md.
Сервер
- .NET 10 / ASP.NET Core, EF Core, PostgreSQL, Redis, опциональный Orleans.
- Реализовано: auth/JWT, онбординг, коллекция, колоды, магазин, экономика, матчмейкинг, WebSocket-матч, история, реплеи.
- Orleans включается
Orleans:Enabled; в compose включён. Один silo, in-process реестр соединений. - Тесты: 151 правил + 45 серверных, CI зелёный.
- Стенд:
http://192.168.31.158:18080,/health→ ok. - Диагностика Ride в
MatchGrain: входящие интенты, результат, события, снапшоты иrideReadyпо руке/рангам; логи черезdocker compose logs. - Документация:
docs/server-api.md,docs/protocol.md,docs/game-rules.md,docs/HANDOFF.md.
Клиент
- Unity 6000.6.6f1, URP; проект в
client/. - Пакеты: URP, Input System, Addressables, Localization, Newtonsoft.Json, VContainer (OpenUPM).
- Визуальное направление: 3D, отдельные сцены-экраны:
Login,Lobby,DeckBuilder,Battle.DeckBuilderсовмещает коллекцию и колоды;Boot— стартовая служебная сцена;VanguardAppперсистентный. - Переходы —
SceneFlow; очередь/онбординг — оверлеи Lobby. - 3D-окружение сейчас из примитивов (
SceneEnvironment): камера, свет, пол, тематические кубы. UI — code-generated uGUI, пока gray-box. - Интерфейс рассчитан на reference 1920×1080 (
CanvasScaler,matchWidthOrHeight = 0.5); standalone принудительно открывается в 1920×1080 fullscreen,defaultIsNativeResolutionвыключен. - Login: тёмный неон + 3D-карточный стол, форма по центру на полупрозрачной панели.
- Сервисы:
ApiClient,AuthService,MetaService,TokenStore,PlayerState,GameConnection. - Работает: логин/регистрация/refresh, онбординг, коллекция с разбором,
декбилдер в духе HS (список колод справа, карточная сетка коллекции,
фильтры в оверлее, сортировка клан→ранг→имя, редактор с вертикальным
списком карт колоды и статистикой по рангам/общему числу),
магазин (бустер/триал-дека), история матчей и реплей, очередь,
WebSocket-матч (snapshot, интенты, маллиган, сдача,
GameFinished), таймер, результат. - Декбилдер:
DeckBuilderView; каталог метаданных —GET /api/cards(grade, trigger, clan, rarity, printing, power/shield/type, текст способности), клиент объединяет с коллекцией. Изображения карт — реальные арты изResources/CardArt(124/124), с процедурным fallback по цвету клана. - ПКМ по карте — оверлей с картой, способностями, разбором в пыль и крафтом; SP/TD не разбираются и не крафтятся.
- Локализация RU/EN:
Loc+LocalizedText; переключатель в Login и Lobby (кнопкаEN/RU), выбор сохраняется вPlayerPrefs. Русские строки остаются ключами, переводятся и статические, и динамические подписи; имена/тексты карт берутся изnameRu/nameEnиtextRu/textEn. - Тренировка с ботом: кнопка «С ботом» в редакторе колоды; сервер
создаёт casual-матч против случайного бота (
POST /api/game/practice), без истории, MMR и наград. - Боевой экран: поле, рука и стопки — 3D (
GameBoard3D), HUD/кнопки остаются uGUI. Карты — тонкие 3D-объекты с артом, рубашкой, торцом и коллайдером. Rest (атака/поддержка) — поворот по часовой стрелке вокруг Y, урон лежит на боку против часовой; закрытость — переворот вокруг X. Рубашка — стандартная VF Vanguard (Resources/CardArt/vanguard_back.png), общая для 2D и 3D. Рука закреплена в поле зрения камеры снизу по центру и всегда смотрит на игрока, а не лежит на столе; уменьшена, чтобы не закрывать задний ряд RC. Камера фиксирована по центру поля под небольшим углом к горизонту и не двигается игроком:(0, 4.2, -8), цель(0, 0, 0), FOV 46; наклон только по X, без бокового смещения. Драг-н-дроп на плоскость стола с подсветкой целей и плавным снапом. Все карты на столе и в руке увеличены на 25% (cardScale = 1.25). - Поле: у каждого игрока два ряда
R V R/R R R(V + 5 RC), у противника зеркально; между полями общий круг защиты; колода, дроп, триггер-зона и урон — 3D-зоны. Локальный игрок всегда снизу, даже если он за вторым местом. Карты в кругах V/R принудительно показываются лицом вверх; урон — один вертикальный ряд, карта входит открытой. Над колодой — зона проверки триггера. Под картами V/R — динамическиеP/C. - Смена: в фазе Ride доступны карты того же ранга и на 1 выше. На первом ходу переход в Battle не предлагается; атака по-прежнему запрещена. Смена — драг карты из руки на VC. Списки всех возможных смен в панелях убраны; действия доступны из меню выбранной карты в руке.
- Призыв: клик по карте в руке открывает меню действий (Призвать / Сменить / Активировать способность / Подробнее), drag в RC/VC выполняет призыв/смену. Если у RC доступен единственный круг перемещения, перемещение выполняется сразу, без выбора цели. Призыв разрешён и в занятый RC; прежний юнит уходит в Дроп. Правило действует для обычного призыва, призыва из души/колоды и выбора круга способностями.
- Аудит всех 66 карт со способностями и правила реализации:
docs/ability-implementation.md. Conroe получил AUTO-call при ride-over. - Способности: кнопка «Активировать способность» одна на карту; при нескольких вариантах открывается overlay выбора способности. Карта для сброса выбирается кликом по карте в руке, а не пунктом меню. Perfect Guard также просит выбрать карту сброса в руке. Клик по карте в руке с активируемой способностью открывает меню действий; пункт активации показывается, если фаза и условия позволяют способность.
- Триггеры: Draw после выбора цели силы сразу тянет карту; Heal выбирает карту только в своей зоне урона и только при выполнении условий, иначе дополнительный эффект не активируется.
- Оплата способности: выбранные карты цены подсвечиваются в руке, а для Counter Blast — доступные и выбранные карты в зоне урона. Подтверждение оплаты — кнопка «Подтвердить оплату» в панели «Действия»; правый клик отменяет выбор.
- Защита: в панели «Действия» одна кнопка — «Не защищаться» без выбора и «Защищаться» с выбранными картами. Защитник из руки должен быть не выше ранга своего авангарда. Карты защиты и перехвата выбираются кликом/драгом по объектам; допустимые подсвечиваются, выбранные — зелёным. Щит выбранных карт сразу учитывается в счётчике; после подтверждения карты уходят в зону защиты, шаг защиты завершается. Дубли карт в Guardian устранены.
- Локальный standalone работает в фоне (
runInBackground), чтобы heartbeat WebSocket не останавливался при потере фокуса. - При потере соединения весь бой блокируется полноэкранным overlay «Соединение потеряно»; автоматический reconnect идёт с задержками 0/2/10/30 с, после успеха overlay скрывается и поле показывается снова. Кнопка внутри overlay позволяет выйти в меню.
- Правую панель действий можно временно скрыть кнопкой «Скрыть панель» в верхней строке; поле остаётся видимым, вернуть — «Показать панель». При скрытии панель действий и блоки противника сдвигаются вправо, а рука центрируется по горизонтали; при показе возвращается влево.
- Кнопка муллигана находится в панели «Действия» и динамическая: без выбора — «Закончить муллиган», с выбором — «Заменить X карт».
- Trigger-зона у противника расположена над его колодой по направлению к центру стола (зеркально своей), а не за дальним краем.
- Статистика карт — отдельное UI-наложение: своя панель снизу слева,
противника — сверху справа. Блоки
Рука/Колода/Дроп/Душа/Урон/Защита/Триггеркликабельны и открывают общий горизонтальныйCardListView; из списка открываетсяCardDetailOverlay. Для колоды и руки противника показываются только закрытые карты. Душа — юниты под VC: отдельной стопки нет, ПКМ по VC открывает список. Дроп по умолчанию пуст; сверху показывает последнюю карту, ЛКМ — список всего дропа. Колода и дроп поменяны местами (колода ближе к игроку). Справа от круга защиты — панель действий: конец муллигана (авто после обмена), скип смены, конец главной/боевой; боевая завершается сама, если нет атак и активаций. Рука противника — веер закрытых карт у дальнего края стола, только рубашки. - Зона урона: карты лежат открытыми и на боку; после Counter Blast выбранная карта переворачивается рубашкой. Heal выбирает карту урона; Counter Blast — открытую карту до активации способности.
- Маллиган: один раз на игрока, оба игрока; выбранные карты уходят в низ колоды, добираются новые, затем shuffle. Клик по руке выбирает карты; кнопка динамическая: без выбора — «Закончить муллиган», с выбором — «Заменить X карт».
- Анимации: event-фидбек (атака, guard, drive, урон, retire, heal) поверх
стола; ввод заблокирован до завершения через
InputLockService, очередь событий + кнопка «Пропустить анимации». Длительности и скорости карт —AnimationConfig(Resources/AnimationConfig). Guard/drive/intercept показывают имя карты и держатся 1.5–2 с. 3D-карты плавно снапятся, поворачиваются в Rest и переворачиваются; подсветка целей и точки броска обновляются на каждом снимке. Зависшие причиныInputLockServiceснимаются, когда reconnect/overlay/ability/card-menu/feedback уже неактивны;board-лок больше не накапливается на каждом снапшоте. - 3D UX (P0/P1):
CardMoveAnimatorпереносит карты по дуге с stagger/InputLock; diff идёт поInstanceId, пул сохраняет карту при смене зоны.AnimationConfigрасширен (moveDuration,importantMoveDuration,moveDelayBetweenCards,arcHeight, camera/grow/dash). Trigger Zone: своя +90°, противника −90° относительно базы;DropZoneFaceDownв конфиге.CameraDirector+TriggerCheckSequence: zoom → hold → return, цепочка, точный Restore;EnsureCameraне перезаписывает камеру во время цепочки.ArrowDirector: красная attack и синяя boost-стрелка, grow/arc/dash (UV-tile), якоря у края карт. Multi-target Counter Blast: выбранные карты урона уходят массивомDamageIndexes, сервер снимает именно их; счётчик выбора показывается в панели «Действия». Детали —docs/3d-ux-backlog.md. - Опциональные AUTO-способности (Barcgal после рейда Marron) открывают
модальный оверлей «Способность» с «Активировать»/«Пропустить»; в боковой
панели этих кнопок нет. После подтверждения призыва сервер предлагает
AskEmptyRearGuardChoice, клиент подсвечивает свободные RC и принимает выбор кликом по кругу — первого круга по умолчанию нет и отдельных кнопок выбора тоже. Сама панель пока оставлена. - Общий верхний
ActionPromptпоказывает, что сейчас требуется: муллиган, смена, защита, бой, выбор карты/круга/цели, триггер, порядок триггеров, опциональная способность. Он не перехватывает клики и скрыт в ход противника. - Правило: выбор карты/круга/зоны/цели делается кликом/драгом по объекту
на поле, не кнопками; кнопки — только глобальные действия/подтверждения.
Зафиксировано в
AGENTS.mdиdocs/client-visual-direction.md. - Бой: динамическая плашка
POWER X vs SHIELD Y(Power атакующего против Power защищающегося + GuardShield), пересчитывается на каждом снимке, в том числе после Guard. От атакующего к цели идёт затухающая 3D-стрелка, которая следует за картами. ЛКМ по своей карте V/R открывает контекстное меню с действиями изLegalIntents(атака/boost, перемещение, способность, подробнее); карты противника и зоны открывают детали/списки. ПКМ по VC — душа. Guardian-карты повёрнуты на 90° и уложены с перекрытием ~30%, новые сверху; Trigger-зона зеркальна у противника. 3D-подписи зон скрыты, включаются флагомshowZoneLabels. - Tejas может атаковать задний ряд противника своей колонки как с RC, так и с VC (центральный задний ряд).
- Drag в бою: задний ряд → свой передний круг/Авангард объявляет поддержку,
после чего атаковать можно только поддерживаемой картой; передний круг →
карта противника объявляет атаку. Авангард поддерживается центральным
задним кругом. Barcgal имеет ACT
[Rest]— поиск Llew/Flogal в колоде с выбором круга призыва; найденные карты показываются оверлеем с плитками карт и выбираются кликом по карте. Morgana после принятия способности просит сбросить карту: доступные карты в руке подсвечиваются, выбор — кликом по карте. - Реальные арты:
imageKeyиз/api/cards+CardImageServiceищетResources/CardArt/{imageKey}. Скачаны все 124 арта. Импорт:tools/import_card_art.py. - Взаимодействие в бою: клик по картам/зонам, подсветка целей, группировка действий (карты → цели, глобальные кнопки отдельно), выбор силы/эффекта триггера, журнал последних событий. Позванные rear-guard'ы входят в стоячем положении; rest — только после атаки/буста. Атака проходит при силе атакующего >= силы защищающегося. В первый ход атака запрещена; первый игрок определяется сидом.
- Отдельная сцена
CollectionиCollectionViewудалены; коллекция открывается из Lobby кнопкой «Коллекция» (сценаDeckBuilder). - Не готово: 3D-модели карт/стола (пока процедурные примитивы и арты),
звук, настройки (язык уже есть), DOTween, drag&drop и live-валидация
декбилдера. Камера боя в покое фиксирована, но
CameraDirectorвременно ведёт trigger-последовательность. Не перенесены отдельные retire/ghost анимации,AttackResolutionQueue, multi-target Soul Blast, world-space Power/Shield.
Запуск
Сервер (на ssh home):
cd ~/VanguardReMaster
docker compose up -d --build
curl http://127.0.0.1:18080/health
Клиент:
- Unity Hub →
client, редактор 6000.6.6f1. - Открыть
Assets/Scenes/Boot.unity, Play. - Стенд по умолчанию —
http://192.168.31.158:18080.
Standalone Windows:
- В редакторе:
Vanguard → Build Windows Standalone. - Из CLI (пример для копии проекта):
& 'C:\Program Files\Unity\Hub\Editor\6000.6.6f1\Editor\Unity.exe' ` -batchmode -nographics -projectPath client ` -executeMethod Vanguard.Editor.StandaloneBuild.BuildWindowsCli -quit - Результат:
client/Builds/Windows/VanguardReMaster.exe(папка в.gitignore). Это обычное приложение, не Play Mode; сервер должен быть доступен по адресу изAppConfig.
Проверки клиента
# EditMode
& 'C:\Program Files\Unity\Hub\Editor\6000.6.6f1\Editor\Unity.exe' `
-batchmode -nographics -projectPath client `
-runTests -testPlatform EditMode -testResults client\TestResults.xml
# Boot → Login + 3D environment
& 'C:\Program Files\Unity\Hub\Editor\6000.6.6f1\Editor\Unity.exe' `
-batchmode -nographics -projectPath client `
-executeMethod Vanguard.Editor.SceneSmoke.Run
# 3D playmat sandbox
& 'C:\Program Files\Unity\Hub\Editor\6000.6.6f1\Editor\Unity.exe' `
-batchmode -nographics -projectPath client `
-executeMethod Vanguard.Editor.SceneSmoke.RunPlaymat
Клиентские проверки: 46/46 EditMode (включая новые тесты TASK-2026-001:
повторный render скрытых карт, открытие урона, source-позиция нового юнита,
coalescing CardMoveAnimator; сборка всех экранов, импорт арта, перевод
строк, live-переключение языка, рендер 3D-доски, геометрия поля, правила
перемещения, рука в поле зрения камеры, обмен колоды/дропа, триггер-зона,
CardListView/Detail, зоны и рука противника, InputLock, контекстное меню,
стрелка атаки, prefab-оверлеи, раскладка на 1920×1080, авто-завершение
муллигана, одна кнопка защиты, отсутствие дублей в Guardian), SCENE_SMOKE success=True, PLAYMAT_SMOKE success=True cards=25 hand=5/5 fieldVisible=True.
SceneSmoke заменяет PlayMode-тест загрузки сцен: Single-загрузка сцены
ломает стандартный PlayMode test runner. SceneBuilder пересобирает сцены:
& '...\Unity.exe' -batchmode -nographics -projectPath client `
-executeMethod Vanguard.Editor.SceneBuilder.BuildAll
Ключевые файлы клиента
client/Assets/Vanguard/Runtime/App/
VanguardApp.cs composition root, персистентный
SceneFlow.cs переходы Login/Lobby/DeckBuilder/Battle
SceneEnvironment.cs 3D-фон сцен
SceneControllerBase.cs
LoginSceneController.cs
LobbySceneController.cs
DeckBuilderSceneController.cs
BattleSceneController.cs
client/Assets/Vanguard/Runtime/UI/
LoginView.cs MetaView.cs OnboardingView.cs
DeckBuilderView.cs QueueView.cs BattleView.cs
UiKit.cs Localization.cs
client/Assets/Vanguard/Runtime/UI/Overlays/
OverlayNavigationService.cs стек список → детали
CardListView.cs общий горизонтальный список
CardDetailOverlay.cs крупная карта и текст
CardListModels.cs зоны и скрытые карты
ZoneBlockStripView.cs кликабельные блоки зон
CardActionMenuView.cs контекстное меню карты
OverlayPrefabs.cs загрузка prefab-оверлеев
client/Assets/Vanguard/Editor/
OverlayPrefabBuilder.cs сборка Resources/Overlays/*.prefab
StandaloneBuild.cs Windows standalone build
client/Assets/Vanguard/Runtime/Battle/
AnimationConfig.cs длительности/скорости анимаций
InputLockService.cs блокировка ввода по причинам
GameConnection.cs
client/Assets/Vanguard/Runtime/Board3D/
Config/PlaymatLayoutConfig.cs ScriptableObject-раскладка
Data/BoardTypes.cs зоны, круги, CardState3D, refs
Logic/PlaymatLayout.cs геометрия, рука, поиск цели броска
Logic/BoardPlacementRules.cs Ride/Call/Move/Guard
View/GameBoard3D.cs стол, круги, пул карт, drag&drop
View/Card3D.cs карта: лицо/рубашка/торец, Rest, флип
View/AttackArrowView.cs стрелка атаки с наконечником
PlaymatSandbox.cs демо без сервера
client/Assets/Vanguard/Resources/AnimationConfig.asset настройки анимаций
client/Assets/Vanguard/Resources/Overlays/*.prefab prefab-оверлеи
client/Assets/Vanguard/Resources/CardArt/vanguard_back.png рубашка VF
client/Assets/Vanguard/Scenes/GameBoard3D.unity песочница поля
client/Assets/Vanguard/Runtime/Api/ApiClient.cs + ApiContracts.cs
client/Assets/Vanguard/Editor/SceneBuilder.cs + SceneSmoke.cs
client/Assets/Vanguard/Scenes/*.unity
client/Assets/Plugins/Vanguard.Shared + MessagePack
Решения
- 3D-визуал, отдельные сцены; подробно —
docs/client-visual-direction.md. Bootне показывается;VanguardApp/сервисы не пересоздаются.- Очередь — оверлей Lobby; DeckBuilder «В бой» возвращает в Lobby с
выбранной колодой в
SceneFlow.PendingQueueDeck. - Токены в
PlayerPrefs— dev; для релиза защищённое хранилище. - HTTP разрешён только для dev (
insecureHttpOption: 2); для релиза HTTPS. GameConnectionиспользуетSystem.Net.WebSockets.ClientWebSocket(Windows/десктоп first); WebGL потребует другого транспорта.- Сервер авторитарный; клиент отправляет только интенты, скрытые данные не покидают сервер.
Следующие шаги
- TASK-2026-001 — ручная проверка пользователем (C10): draw, call, ride,
move/swap, guard, trigger, drive/damage, retire, search, открытие скрытого
урона, рука противника, повторные клики UI во время/после анимации.
Автотесты 46/46; код изменён в
GameBoard3D,CardMoveAnimator,BattleView,AnimationConfig.asset+ тесты. - 3D UX: P0 (движение, ориентации, камера/триггер) и базовый P1 (стрелки,
multi-target Counter Blast) готовы. Осталось:
AttackResolutionQueue, multi-target Soul Blast/прочие стоимости, отдельныйCostPaymentOverlay, world-space Power/Shield (верхний strip принят как HUD), world-space dash shader; полировка позиций на конкретном мониторе. - Декбилдер: drag&drop, счётчики лимитов, live-валидация, пресеты.
- 3D-наполнение: модели карт/стола, prefab-экраны сцен, анимации retire/ghost.
- Звук и настройки, DOTween.
- Лаунчер WPF.
Тренировка с ботом и боевой UI с артами/анимациями/локализацией уже есть.
Подводные камни
- Не запускать
dotnet/Docker на рабочем ПК; сервер проверяется наssh home. - В Unity нельзя открыть два экземпляра одного проекта: для batch-проверок
делать копию проекта (без
Library) или закрывать редактор. - Сцены ссылаются на скрипты по GUID; при копировании сцен копировать и
.metaконтроллеров. Vanguard.Shared.dll— netstandard2.1 + MessagePack 3.1.12; при изменении протокола пересобрать DLL и заменить вclient/Assets/Plugins.UiKit.CreateCanvasпо умолчанию не персистентный: Canvas принадлежит сцене; EventSystem остаётся персистентным.- Сцена
Bootдолжна быть первой в Build Settings; сейчас тамBoot,Login,Lobby,DeckBuilder,Battle.