242 lines
17 KiB
Markdown
242 lines
17 KiB
Markdown
# Правила Vanguard ReMaster (Classic)
|
||
|
||
Статусы: **[D]** подтверждено пользователем, **[C]** подтверждено кодом,
|
||
**[O]** неизвестно/расхождение. Полный конспект официальных правил и сверка —
|
||
`docs/game-rules.md`; здесь рабочая база проекта.
|
||
|
||
## 1. Формат и матч
|
||
|
||
- **[D]** Формат проекта — **Classic**: BT01 + TD01/TD02. Не Standard,
|
||
Premium или G Standard.
|
||
- **[D]** Матч BO1; сайд-дека нет.
|
||
- **[D]** В Classic нет Ride Deck, Persona Ride, Stride, Legion, Gift,
|
||
G-зоны, Bind, Front/Over-триггеров и Grade Support.
|
||
- **[C]** В матче два игрока; первый определяется seeded RNG, но может быть
|
||
зафиксирован тестом/сервером.
|
||
- **[C][D]** Первый ход: нет Battle и атак. `GameEngine` умеет отключать это
|
||
правило флагом для тестов, но серверный матч использует запрет.
|
||
- **[D]** Таймер: 90 секунд на ход + банк 5 минут; отсутствие 5 минут —
|
||
поражение. Реконнект: 0/2/10/30 секунд, затем полный snapshot.
|
||
- **[C]** Победа/поражение: 6 карт урона, пустая колода, сдача/выход/разрыв,
|
||
истечение времени или отсутствие. Дополнительное условие «авангард исчез»
|
||
есть в конспекте, но отдельной проверки в `GameEngine` нет — **[O]**.
|
||
|
||
## 2. Колода
|
||
|
||
**[D][C]** Основная колода:
|
||
|
||
- ровно **50 карт**;
|
||
- ровно **16 триггер-карт**;
|
||
- не более **4 копий одной карты по `nameId`**, а не по принту/арту;
|
||
- не более **4 Heal-триггеров**;
|
||
- не более **4 Sentinel**;
|
||
- стартовый авангард — карта grade 0 без триггера; движок выбирает первого
|
||
подходящего кандидата из колоды;
|
||
- **смешивать кланы разрешено** [D, 2026-10-24]. Это осознанное отклонение от
|
||
официального ограничения: эффекты, требующие клан/условие, могут не
|
||
сработать. `DeckValidator` единство клана не проверяет.
|
||
- Колода должна быть собрана из карт, которыми владеет игрок (проверка
|
||
`DeckService`); в коллекции лимита копий нет — 4 копии ограничивают только
|
||
колоду.
|
||
- **[O]** Легальность по формату/banlist и обязательное наличие ровно одного
|
||
стартового авангарда в `DeckValidator` отдельно не выделены.
|
||
|
||
## 3. Начало партии
|
||
|
||
1. Перемешать колоды.
|
||
2. Положить стартового авангарда grade 0 без триггера в VC закрытым.
|
||
3. Взять по 5 карт.
|
||
4. Mulligan: каждый игрок один раз может вернуть любое количество карт
|
||
**в низ колоды**, добрать столько же сверху, затем перемешать. Оба игрока
|
||
проходят этап. Возвращённые карты не должны попасть в тот же добор.
|
||
5. Открыть стартовых авангардов; первый игрок начинает.
|
||
|
||
**[C]** В коде `MulliganCommand` сразу выполняет возврат → добор → shuffle, а
|
||
`FinishMulliganCommand` передаёт очередь второму игроку; отдельной команды
|
||
«выбрать карты и подтвердить» нет.
|
||
|
||
## 4. Зоны
|
||
|
||
| Зона | Смысл |
|
||
|---|---|
|
||
| Deck | закрытая колода, добор сверху |
|
||
| Hand | рука; у противника видно только количество |
|
||
| Vanguard Circle (VC) | текущий авангард; под ним — Soul |
|
||
| Rear-guard Circles (RC) | 5 кругов: 0/1/2 задний ряд, 3/4 передний |
|
||
| Guardian Circle (GC) | временная зона защитников/перехватчиков |
|
||
| Damage | урон; 6+ — поражение |
|
||
| Drop | сброс/уничтоженные карты |
|
||
| Trigger | временная зона проверки триггера |
|
||
| Soul | карты под VC, не отдельная стопка на поле |
|
||
|
||
- **[C]** Карты на VC/RC/GC открыты. Закрытыми могут быть рука/колода и урон
|
||
после Counter Blast.
|
||
- **[C]** Урон входит **лицом вверх**; Counter Blast переворачивает выбранные
|
||
карты лицом вниз; Counter Charge — обратно.
|
||
- **[D]** Рука противника отображается только рубашкой; колода — только
|
||
количеством; урон лицом вниз — только количеством.
|
||
- **[C]** Soul не показывается на столе; доступна через ПКМ/список у VC.
|
||
- **[D]** Drop по умолчанию пуст; сверху показывается последняя карта, по
|
||
клику — весь список.
|
||
|
||
## 5. Фазы хода
|
||
|
||
**[C]** Порядок в движке: `Stand → Draw → Ride → Main → Battle → End`.
|
||
Mulligan — отдельная фаза до первого хода.
|
||
|
||
### Stand
|
||
|
||
Все юниты активного игрока в Rest поднимаются, если нет `CannotStand`.
|
||
Ограничения `UntilOwnerNextStand` снимаются после подъёма.
|
||
|
||
### Draw
|
||
|
||
Взять 1 карту сверху. Пустая колода — поражение.
|
||
|
||
### Ride
|
||
|
||
- Карта из руки на VC; ранг **равен текущему или на 1 выше**.
|
||
- Старый авангард уходит в Soul.
|
||
- Ride — один раз за ход; можно пропустить.
|
||
- Новый авангард входит стоя и открытым.
|
||
- **[C]** После Ride сначала срабатывает `OnPlace` новой карты, затем
|
||
`OnRideOver` старой; если `OnPlace` открыл pending-способность, текущая
|
||
реализация не запускает `OnRideOver` до её завершения. Это техническая
|
||
деталь, а не новое правило; при работе с такими картами проверяй сценарий.
|
||
|
||
### Main
|
||
|
||
- **Call**: из руки в RC; grade ≤ grade своего VC. Занятый RC разрешён:
|
||
прежний юнит уходит в Drop. Призыв из soul/deck и выбор круга работают так
|
||
же. Число призывов не ограничено. Юнит входит стоя.
|
||
- **Move**: RC ↔ RC только в своей колонке: 0↔3, 2↔4; занятые меняются
|
||
местами. VC в Move не участвует.
|
||
- **Activate**: ACT-способности; AUTO срабатывают по событиям.
|
||
- **End Main**: переход в Battle.
|
||
- **[C]** В Main также доступны `EndTurn` и (если разрешено) `EnterBattle`.
|
||
|
||
### Battle
|
||
|
||
1. Атака: стоящий юнит **переднего ряда** (VC или RC 3/4), он уходит в Rest.
|
||
Цель — VC или передний RC противника.
|
||
2. Boost: стоящий юнит 0/1 ранга из заднего ряда той же колонки уходит в Rest;
|
||
его сила добавляется атакующему до конца боя. Карта может получить Boost
|
||
эффектом.
|
||
3. Guard: защищающийся добавляет карты из руки в GC. Grade ≤ grade своего
|
||
авангарда. Щит добавляется сразу.
|
||
4. Intercept: подходящий RC (обычно grade 2, передний ряд) выходит в GC;
|
||
атака переносится на него. Нельзя перехватывать атаку по самому себе.
|
||
5. Drive Check: только из VC; 0–2 ранг — 1 проверка, 3+ — 2; эффект может
|
||
изменить/обнулить. Арьергард по умолчанию проверок не делает.
|
||
6. Сравнение: сила атакующего **>=** силы защищающегося + щит — попадание.
|
||
Иначе промах. При попадании по RC цель уходит в Drop; при попадании по VC
|
||
наносится урон, равный критическому удару.
|
||
7. Damage Check: по одной карте за урон; триггеры срабатывают, затем карта
|
||
идёт в Damage.
|
||
8. После боя Guardian/Intercept уходят в Drop. Атакующий может атаковать
|
||
снова, если есть стоящие передние юниты.
|
||
|
||
**[C]** Boost/Interceptor/Guard карты и их модификаторы очищаются в
|
||
`ClearBattle`; `UntilEndOfBattle` не переживает бой.
|
||
|
||
### End
|
||
|
||
Сначала возвращаются карты с `ReturnToDeckTiming.EndOfTurn`, затем снимаются
|
||
`UntilEndOfTurn` модификаторы/выданные способности/ограничения. Ход переходит
|
||
противнику, начинается Stand.
|
||
|
||
## 6. Атака, защита, крит и урон
|
||
|
||
- **[C]** Обычная цель — только VC или передний RC. Задний ряд можно атаковать
|
||
только `CanSnipeBackRow` (Tejas) и только в своей колонке. Tejas бьёт задний
|
||
ряд и с VC (центральная колонка), и с RC.
|
||
- **[C]** Атака/Boost/часть ACT переводят карту в Rest.
|
||
- **[C]** Guard: `def.Grade > VanguardGrade` отклоняется. Sentinel сам по себе
|
||
даёт 0 щита. Perfect Guard: сброс карты **того же клана** отменяет атаку;
|
||
без оплаты — 0 щита и отмены нет. Сброс — опциональная стоимость.
|
||
- **[C]** Guard/Intercept карты после боя уходят в Drop; `OnLeaveGuardian`
|
||
срабатывает после закрытия боя.
|
||
- **[C]** Урон — лицом вверх; 6-я карта вызывает поражение после разрешения
|
||
эффектов. Damage Check-триггер сначала кладёт карту в Trigger, применяет
|
||
эффект, затем в Damage.
|
||
- **[C]** Heal доступен, если урон игрока **>=** урона соперника и в своей
|
||
зоне есть карты; лечится карта только из своей зоны урона.
|
||
|
||
## 7. Триггеры
|
||
|
||
**[D][C]** В Classic только Critical, Draw, Stand, Heal. Front/Over — нет.
|
||
|
||
- Триггеры срабатывают при Drive Check и Damage Check.
|
||
- Базовый бонус силы — **+5000**; действует до конца хода.
|
||
- Power target и второй эффект могут быть разными юнитами, если текст не
|
||
запрещает.
|
||
- **Critical**: +5000 и +1 крит выбранному юниту.
|
||
- **Stand**: +5000 и поднять выбранного отдыхающего арьергарда; если
|
||
арьергардов нет, второй эффект не применяется.
|
||
- **Draw**: +5000 и немедленно взять карту; отдельной цели для draw нет.
|
||
- **Heal**: +5000 и, при условии, лечение 1 урона из своей зоны; если нет
|
||
карт/условия — лечение не активируется.
|
||
- **[C]** На Damage Check `GrantsPower = true`: усиление тоже применяется.
|
||
- После Drive Check карта уходит в руку; после Damage Check — в Damage.
|
||
- Бонусы триггеров снимаются в конце хода, в том числе у противника.
|
||
|
||
## 8. Стоимости
|
||
|
||
| Стоимость | Реализация |
|
||
|---|---|
|
||
| Counter Blast X | перевернуть X **открытых** карт урона лицом вниз; при выборе — конкретные |
|
||
| Counter Charge X | перевернуть X закрытых карт лицом вверх; если меньше — сколько есть |
|
||
| Soul Blast X | X карт из Soul в Drop |
|
||
| Soul Charge X | X верхних карт колоды в Soul |
|
||
| Discard | выбранная карта из руки в Drop |
|
||
| Rest self | повернуть источник |
|
||
| Retire self | убрать источник в Drop |
|
||
|
||
- **[D]** Multi-target Counter Blast: клиент выбирает карты урона; сервер
|
||
принимает `DamageIndexes` и переворачивает именно их. Старый одиночный
|
||
`DamageIndex` сохранён для совместимости.
|
||
- **[O]** Multi-target Soul Blast и другие стоимости ещё не имеют такого же
|
||
выбора/протокола.
|
||
- **[D]** Стоимость выбирается по объектам, подтверждение — отдельной кнопкой
|
||
панели/оверлея; отдельный `CostPaymentOverlay` требуется, но пока не
|
||
реализован (текущий CB использует счётчик в панели «Действия»).
|
||
|
||
## 9. Эффекты и порядок разрешения
|
||
|
||
- **[C]** Источник истины — `GameEngine`; он меняет `GameState` и пишет
|
||
`GameEvent`.
|
||
- **[D]** Эффект, сработавший при прохождении атаки, разрешается **после**
|
||
получения урона и помещения карты в Damage.
|
||
- **[D]** Нельзя начинать новый эффект посреди текущего: цепочка идёт строго
|
||
друг за другом. `_resolvingDepth` складывает новые триггеры в
|
||
`PendingQueue`; после завершения текущего они предлагаются/разрешаются.
|
||
- **[D]** Рекурсию не поддерживаем; при найденном кейсе — отдельное решение.
|
||
- Несколько одновременных AUTO: игрок выбирает порядок; активный игрок первым
|
||
получает доступ к своим срабатываниям (`PendingOrder`/`SelectTriggerCommand`).
|
||
- Optional AUTO: движок спрашивает «активировать/пропустить»; без `Pay`
|
||
эффект не выполняется. `CanPay` проверяется до предложения.
|
||
- CONT пересчитывается из состояния; вычисленную силу не хранить как истину.
|
||
- Модификаторы/способности/ограничения имеют источник, `EffectId` и
|
||
`ModifierDuration`: `UntilEndOfBattle`, `UntilEndOfTurn`,
|
||
`UntilOwnerNextStand`, `Permanent`.
|
||
- `OnPlace` не должен срабатывать от VC, если текст требует RC; проверяй
|
||
`IsVanguardOf`/`IsRearGuardOf`/`IsInHand`.
|
||
|
||
## 10. Особые случаи
|
||
|
||
- **[D]** Move: если у RC доступен только один круг в колонке, клиент
|
||
выполняет перемещение сразу, без выбора цели.
|
||
- **[D]** Draw после выбора цели силы сразу тянет карту; второй цели нет.
|
||
- **[D]** Heal просит цель только в своей зоне урона и только при выполнении
|
||
серверных условий.
|
||
- **[D]** Tejas атакует задний ряд своей колонки с VC/RC.
|
||
- **[D]** Подсветка урона ограничена зоной урона локального игрока и режимом
|
||
оплаты; вне оплаты урон не подсвечивается.
|
||
- **[D]** Call в занятый RC заменяет юнита; старый уходит в Drop.
|
||
- **[D]** В первый ход атака и переход в Battle недоступны.
|
||
- **[C]** `OnRideOver` текущей реализации срабатывает после `OnPlace`, но
|
||
может быть отложен/пропущен при pending-способности `OnPlace`; это
|
||
техническая граница, проверяй карты с обоими окнами.
|
||
- **[O]** Отдельная проверка «авангард исчез» в `GameEngine` не реализована;
|
||
не описывай её как гарантированное поражение без решения.
|