docs: план переделки DeckBuilder (TASK-2026-023)
CI / test (push) Successful in 2m31s Details

- Решения: один экран с панелями «Мои колоды»/«Колода»; превью — только
  иллюстрация карты; фильтры — модальный оверлей с мультивыбором клана,
  грейда и триггера; сортировка колоды грейд → имя, группировка по nameId.
- Чек-лист C1-C11: обрезка иллюстрации, один экран, корректный список
  колод и карт, live-валидация, тесты и проверки.
This commit is contained in:
MpakobecEx 2026-10-31 20:49:17 +05:00
parent 179aa31da6
commit 1999ccb3d8
2 changed files with 231 additions and 1 deletions

View File

@ -43,6 +43,7 @@
| TASK-2026-020 | `[x]` | Парсер карт и артов с официального сайта | DeepSeek: анализ и реализация | идемпотентность 0 diff; `validate` не запускался | | TASK-2026-020 | `[x]` | Парсер карт и артов с официального сайта | DeepSeek: анализ и реализация | идемпотентность 0 diff; `validate` не запускался |
| TASK-2026-021 | `[!]` | Login по референсу: 2D-арт и неоновый UI | DeepSeek: C1–C9, Tab/Enter/Esc; ждёт приёмки | EditMode 60/60; `SCENE_SMOKE success=True`; standalone собран; ручная — пользователь | | TASK-2026-021 | `[!]` | Login по референсу: 2D-арт и неоновый UI | DeepSeek: C1–C9, Tab/Enter/Esc; ждёт приёмки | EditMode 60/60; `SCENE_SMOKE success=True`; standalone собран; ручная — пользователь |
| TASK-2026-022 | `[!]` | Lobby по референсу: дашборд, заглушки, сцена Community | DeepSeek: C1–C11 реализованы; ждёт ручной приёмки | EditMode 62/62; `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone; ручная — пользователь | | TASK-2026-022 | `[!]` | Lobby по референсу: дашборд, заглушки, сцена Community | DeepSeek: C1–C11 реализованы; ждёт ручной приёмки | EditMode 62/62; `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone; ручная — пользователь |
| TASK-2026-023 | `[ ]` | DeckBuilder: один экран, мультифильтры и список колоды | DeepSeek: анализ и план готовы; реализация ожидает | не выполнена |
Новые задачи добавляются в конец файла отдельными разделами. Не используй один Новые задачи добавляются в конец файла отдельными разделами. Не используй один
раздел для нескольких независимых задач. раздел для нескольких независимых задач.
@ -2343,6 +2344,233 @@ HUD с номером хода и фазовой шкалой, компактн
- **Skill обновлён:** не требуется; правила и архитектура не менялись. - **Skill обновлён:** не требуется; правила и архитектура не менялись.
- **Git:** не коммитилось. - **Git:** не коммитилось.
---
### TASK-2026-023 — DeckBuilder: один экран, мультифильтры и список колоды
- **Статус:** `[ ]`
- **Создано:** 2026-10-31
- **Анализ:** DeepSeek выполнен
- **Реализация:** не начата
- **Проверка:** не выполнена
- **Затронутые системы:** `Runtime/UI/DeckBuilderView.cs`,
`Runtime/UI/CardImageService.cs`, `Localization.cs`, EditMode-тесты.
Сервер, правила, протокол и YAML не меняются.
#### A. Цель и требования
Переделать декбилдер по решениям пользователя от 2026-10-31:
1. **Один экран** вместо двух: слева коллекция, справа панель, которая
переключается между «Мои колоды» и «Колода» при входе в редактор.
2. **Мультивыбор фильтров** по клану, грейду и триггеру в модальном
оверлее; выбранные значения подсвечены, есть «Применить» и «Сбросить».
3. **Корректный список колод** справа: имя, `50/50`, `T 16/16`, формат,
распределение по грейдам, бейдж валидности, подсветка открытой колоды.
4. **В редакторе** справа вместо списка колод — карты этой колоды: превью
**только иллюстрации** карты (без рамки и текста, без искажений), имя,
количество; сортировка **грейд → имя**; группировка по `nameId`.
5. Live-валидация 50/16/4; «Сохранить» и «В бой» активны только для
валидной сохранённой колоды.
6. Поведение сохранения, создания, удаления, крафта и разбора не меняется.
7. Геймплей и визуальную приёмку проверяет пользователь.
Критерии готовности:
- переключение «список колод ⇄ колода» не пересоздаёт сцену и не теряет
выбранные фильтры;
- мультивыбор клана/грейда/триггера реально фильтрует коллекцию и
отображается в сводке;
- в списке колоды одна строка на карту (`nameId`), превью — иллюстрация
без растяжения, порядок грейд → имя;
- список колод показывает валидность и счётчики, открытая колода
подсвечена;
- существующие EditMode-тесты и смоуки проходят.
#### B. Текущее состояние
- `DeckBuilderView` (1435 строк) строит два полноэкранных режима
(`DeckList` и `DeckEditor`) с отдельными топбарами и двумя гридами
коллекции; переключение — `ShowEditor`/`BackToList`.
- Правая колонка фиксирована на 300 px: в списке — ряды 76 px
(`имя`, `N/50 · classic`), в редакторе — ряды 64 px
(превью 36×50, `G`, имя, `×N · триггер`).
- Колода хранится как список `printingId`; в редакторе группируется по
`printingId` и сортируется по нему же. Одна карта в разных принтах даёт
две строки, хотя лимит 4 копии считается по `nameId`.
- Фильтры — модальный оверлей: одиночные значения (клан, грейд, триггер),
выбранное состояние не подсвечивается, сводка показывает по одному
значению.
- `CardImageService.Apply` ставит `preserveAspect = false`: арты 350×511
растягиваются в область 174×112 (сетка) и 36×50 (список).
- Валидация выполняется только при сохранении; кнопки активны всегда.
- Тестов на фильтрацию/сортировку нет; `ClientSmokeTests` только создаёт
`DeckBuilderView`.
Что сохранить:
- загрузку коллекции/каталога/колод и контракты `MetaService`;
- лимиты 50/16/4 и правила добавления/удаления;
- оверлей карты (ПКМ), крафт/разбор;
- сцена `DeckBuilder` и переходы `SceneFlow`;
- 3D-окружение сцены не трогать в этой задаче.
#### C. Чек-лист изменений
- [ ] **C1. `MODIFY` `Runtime/UI/CardImageService.cs`** — превью
иллюстрации.
- `ApplyIllustration(Image, imageKey, fallback)`: спрайт из верхней части
карты — `Rect(0, h * 0.41, w, h * 0.59)` для 350×511 (иллюстрация до
полосы флейвора), с кешем по `imageKey`.
- `preserveAspect = true`; выравнивание — центральное; при отсутствии
арта — процедурный fallback без обрезки.
- Полный арт (`Apply`) не меняется: он нужен карточке и 3D-картам.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: нет.
- [ ] **C2. `MODIFY` `Runtime/UI/DeckBuilderView.cs`** — один экран.
- Убрать `_listView`/`_editorView` и `BackToList`; оставить один корень
`DeckBuilderScreen`: топбар (назад в Lobby, заголовок, фильтры,
сброс, статус) и тело (коллекция + правая панель).
- Правая панель: `DeckListPanel` и `DeckPanel` (карты колоды), видимость
переключается; при открытии колоды — `DeckPanel`, кнопка «К списку
колод» возвращает `DeckListPanel`.
- Ширина правой панели 380 px; содержимое — без пересоздания сцены.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C1, C3, C4.
- [ ] **C3. `MODIFY` список колод.**
- Строка: имя, `N/50`, `T N/16`, формат (`Classic`, локализовано),
распределение `G0…G3`, бейдж «Готова / Не готова».
- Валидность считать локально (50 карт, 16 триггеров, ≤4 по `nameId`).
- Подсветка открытой колоды; кнопка «Создать колоду» — над списком.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C2.
- [ ] **C4. `MODIFY` список карт колоды.**
- Группировать по `nameId`, счётчик — сумма принтов; превью — первая
карта группы.
- Строка 84 px: иллюстрация 64×54 (пропорция 1.18), имя (2 строки),
бейдж `G`, `×N`, триггер.
- Сортировка: `Grade` → `Loc.CardName` (`StringComparer.Ordinal`).
- Клик по строке — убрать одну копию; ПКМ — карточка. Счётчики и
валидация обновляются сразу.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C1, C2.
- [ ] **C5. `MODIFY` фильтры — мультивыбор.**
- Хранить `HashSet<string> Clans`, `HashSet<int> Grades`,
`HashSet<string> Triggers`; пустой набор = «все».
- Оверлей: группы чипов с подсветкой выбранного, «Все»/«Сбросить»,
«Применить» (применяет черновик) и «Отмена» (откатывает).
- Сводка в топбаре: `Клан: RP, Kagero · Ранг: 0, 1 · Триггер: Heal`.
- `MatchesFilter` проверяет вхождение во все активные наборы.
- После применения — пересборка коллекции; счётчики в ячейках
обновляются без полного пересоздания (если возможно).
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C2, C6.
- [ ] **C6. `MODIFY` фильтрация и сортировка — чистый класс.**
- Вынести в `Runtime/UI/DeckListFilter.cs` (или статический helper):
`Matches(meta, filter)`, `SortDeck(cards, catalog)`, `GroupDeck(...)`.
- Фильтр: наборы клана/грейда/триггера; сортировка колоды: грейд → имя;
группировка по `nameId`.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C4, C5.
- [ ] **C7. `MODIFY` ячейки коллекции.**
- Иллюстрация через `ApplyIllustration`, область арта с правильной
пропорцией (например, 174×147), без растяжения.
- Показывать `×в колоде` по `nameId`; при достижении лимита 4 или 16
триггеров — приглушать и не добавлять.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C1, C5.
- [ ] **C8. `MODIFY` live-валидация.**
- `UpdateStats` дополнить статусом валидности и цветом счётчиков;
«Сохранить», «В бой», «С ботом» — `interactable` только при валидной
сохранённой колоде.
- Ошибки лимитов — в статусе редактора, без модальных окон.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C3, C4.
- [ ] **C9. `MODIFY` `Runtime/UI/Localization.cs`** — новые ключи.
- «Мои колоды», «К списку колод», «Готова», «Не готова», «Клан: »,
«Ранг: », «Триггер: », «Применить», «Отмена», «Все кланы»,
«Все ранги», «Все триггеры», «Иллюстрация» и подписи счётчиков.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C2–C5.
- [ ] **C10. `TEST` EditMode.**
- `DeckListFilter`: мультивыбор клана/грейда/триггера, пустой набор =
все; сортировка грейд → имя; группировка по `nameId` суммирует принты.
- `CardImageService`: обрезка иллюстрации возвращает неполный rect
(проверка по спрайту/текстуре без реального файла — на fallback).
- UI: один экран, переключение панелей, сводка фильтров, бейдж
валидности.
- Существующий `Client_Views_Build` — без изменений ожиданий.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C1–C9.
- [ ] **C11. `VERIFY` EditMode, smoke, standalone.**
- Копия без `Library`; EditMode; `SCENE_SMOKE`; standalone.
- Ручная проверка: фильтры, список колод, редактор, добавление/удаление,
сохранение, «В бой»/«С ботом», ПКМ-карточка.
- Реализация: не выполнена. Проверка: не выполнена.
- Зависит: C10.
#### D. Последовательность выполнения
1. C1 + C6: обрезка иллюстрации и чистые функции фильтра/сортировки/групп.
2. C2: один экран и переключение правой панели.
3. C3–C4: список колод и список карт колоды.
4. C5 + C7: мультифильтры и ячейки коллекции.
5. C8–C9: валидация и локализация.
6. C10–C11: тесты, smoke, standalone, ручная приёмка.
#### E. Проверки
- EditMode в копии без `Library`.
- `SceneSmoke.Run`, `RunPlaymat`, standalone-сборка.
- `git diff --check`; нет изменений в `server/`, `content/`, `Vanguard.Rules`.
- Ручная проверка — пользователь.
#### F. Решения и риски
**Зафиксировано пользователем (2026-10-31):**
1. Один экран с двумя панелями.
2. Превью — только иллюстрация карты (без рамки и текста).
3. Фильтры — модальный оверлей с мультивыбором.
4. Триггерный фильтр — тоже мультивыбор.
5. Сортировка карт колоды — грейд → имя; группировка по названию.
**Риски:**
- **Границы иллюстрации:** доля 0.59 снята с BT01/TD01 (350×511); если
встретится другой макет карты, полоса флейвора может попасть в кадр.
Константы вынести в одно место и проверить на нескольких сетах.
- **Группировка по `nameId`:** при смешанных принтах в строке показывается
иллюстрация первого; удаление уменьшает суммарный счётчик.
- **Один экран:** легко потерять состояние (открытая колода, черновик
фильтров). Хранить явно и сбрасывать только по действию пользователя.
- **Пересборка грида:** при смене фильтра она неизбежна; не пересобирать
на каждый клик добавления — обновлять счётчики точечно.
- **Валидность:** локальная проверка должна совпадать с серверной
(`DeckValidator`), иначе «Сохранить» включится, а сервер откажет.
- **3D-фон DeckBuilder** остаётся; если позже переведём на 2D, это
отдельная задача.
**Открытых вопросов, блокирующих старт, нет.**
#### G. Результат
- **Реализовано:** —
- **Проверки:** —
- **Не завершено/заблокировано:** —
- **Skill обновлён:** —
- **Git:** —

View File

@ -375,7 +375,9 @@ client/Assets/Plugins/Vanguard.Shared + MessagePack
(C10). EditMode 60/60, `SCENE_SMOKE success=True`, standalone собран. (C10). EditMode 60/60, `SCENE_SMOKE success=True`, standalone собран.
**TASK-2026-022 — Lobby по референсу: реализован C1–C11, ждёт ручной **TASK-2026-022 — Lobby по референсу: реализован C1–C11, ждёт ручной
приёмки.** EditMode 62/62, `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone приёмки.** EditMode 62/62, `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone
собраны и запущены. После приёмки — **TASK-2026-019** (загрузочная собраны и запущены. **TASK-2026-023 — DeckBuilder (один экран,
мультифильтры, список колоды): анализ и план готовы**, реализация —
следующим проходом. После приёмки — **TASK-2026-019** (загрузочная
сцена, fade, кадр без покадровых аллокаций). сцена, fade, кадр без покадровых аллокаций).
2. **TASK-2026-001 — ручная проверка пользователем** (C10): draw, call, ride, 2. **TASK-2026-001 — ручная проверка пользователем** (C10): draw, call, ride,
move/swap, guard, trigger, drive/damage, retire, search, открытие скрытого move/swap, guard, trigger, drive/damage, retire, search, открытие скрытого