Статус: Ready
Канонический полный список боевых статов (
StatType): EN-основа + RU, операция-модификатор, дефолт, клампы, фаза внедрения. Опирается на стат-механику из 6. Боевая модель §3 (слоистые модификаторы, формула,ScalableValue). Дизайнерское описание «что это для игрока» — GDD: 8. Статы.
1. Решённые принципы
- Бой детерминированный. В пути урона нет RNG: крита нет, уклонения нет. RNG входит в игру позже и только через
IRngService(процы эффектов — Фаза 2; лут/генерация карты — Фаза 5). - Крит — отложен. Если когда-нибудь появится — будет детерминированным (например «каждый 3-й удар — крит», счётчик), а НЕ случайным. Это сохраняет детерминизм. Сейчас стата крита нет.
- Уклонение/промах — нет. Выживаемость покрыта HP / бронёй /
DamageTakenEff/ щитами. - Статы = слоистые модификаторы с источником (не плоский класс из 30 полей). Формула:
final = (base + ΣFlat) × (1 + ΣPercentAdd) × Π(1 + PercentMult). Пересчёт по dirty-флагу. - «Эффективности» — это
StatTypeсо стартом1.0и натуральной операциейPercentMult. Никакого спец-кода в десяти местах. - Числовое vs категориальное: через модификаторы идут только числа. Категории — конфигурация на
RelicData.
2. Категориальная конфигурация (НЕ статы, на RelicData)
| Поле | Значения |
|---|---|
DamageType | Physical (физ) / Magic (маг) / True (чистый — игнорирует броню) |
AttackType | Melee (ближний, мгновенный) / Ranged (снаряд) / ProjectileAoe (снаряд + AOE в точке попадания) / ProjectilePierce (пробивающий снаряд) |
ResourceType | None / Mana / Rage / … (типы и их реген — прорабатываются позже) |
3. Полный список статов (ровно 30)
Op = «натуральная» операция базы. Все статы могут получать модификаторы любой операции (Flat/PercentAdd/PercentMult).
3.1 Выживаемость
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
MaxHP | Макс. здоровье | Flat | — | ≥ 1 | ✅ |
HpRegenFlat | Реген HP (число/сек) | Flat | 0 | ≥ 0 | ✅ |
HpRegenPct | Реген HP (% макс/сек) | Flat | 0 | ≥ 0 | ✅ |
PhysArmor | Физ. броня | Flat | 0 | может быть < 0 (см. §4) | ✅ |
MagicArmor | Маг. броня | Flat | 0 | может быть < 0 (см. §4) | ✅ |
DamageTakenEff | Эфф. получаемого урона | PercentMult | 1.0 | ≥ 0 (0 = иммун) | ✅ |
HealShieldTakenEff | Получаемая сила исцеления/щитов | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
3.2 Атака
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
AutoAttackDamage | Урон автоатаки | Flat | — | ≥ 0 | ✅ |
AttackSpeed | Скорость атаки (атак/сек) | PercentAdd | — | [0.1, 2.5] из StatsConfig | ✅ |
AttackRange | Дальность атаки | Flat | — | ≥ 0 | ✅ |
AbilityPower | Сила навыков (AP) | Flat | 0 | ≥ 0 | ⛔ Ф2 |
PhysPen | Физ. пробивание (плоское) | Flat | 0 | ≥ 0 | ✅ |
PhysPenPct | Физ. пробивание (%) | Flat | 0 | [0, 1] | ✅ |
MagicPen | Маг. пробивание (плоское) | Flat | 0 | ≥ 0 | ✅ |
MagicPenPct | Маг. пробивание (%) | Flat | 0 | [0, 1] | ✅ |
DamageDealtEff | Эфф. наносимого урона | PercentMult | 1.0 | ≥ 0 | ✅ |
Lifesteal | Вампиризм (% от нанесённого урона) | Flat | 0 | ≥ 0 | ✅ |
3.3 Исцеление / щиты
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
HealShieldDealtEff | Исходящая сила исцеления/щитов | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
3.4 Снаряд
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
ProjectileSpeed | Скорость снаряда (ед/сек) | Flat | — | > 0 | ✅ |
ProjectilePierce | Пробивание снаряда (кол-во целей) | Flat | 0 | ≥ 0, целое | ✅ |
3.5 Подвижность
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
MoveSpeed | Скорость передвижения (ед/сек) | Flat | — | ≥ 0 | ✅ |
Size | Размер юнита | Flat | 1.0 | > 0 | ✅ |
3.6 Эффективность эффектов
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
ApplyBuffEff | Эфф. наложения положит. эффектов | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
ApplyDebuffEff | Эфф. наложения негат. эффектов | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
ReceiveBuffEff | Эфф. получаемых положит. эффектов | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
ReceiveDebuffEff | Эфф. получаемых негат. эффектов (= tenacity) | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
CooldownEff | Эфф. перезарядки (× времени КД, < 1 = быстрее) | PercentMult | 1.0 | > 0 | ⛔ Ф2 |
3.7 Ресурс (только геройские реликвии)
| EN | RU | Op | Старт | Кламп | Ф1 |
|---|---|---|---|---|---|
MaxResource | Макс. запас ресурса | Flat | 0 | ≥ 0 | ⛔ Ф2 |
StartResource | Начальный запас (init-only, читается раз при сборке) | Flat | 0 | [0, MaxResource] | ⛔ Ф2 |
ResourceGainEff | Эфф. получения ресурса | PercentMult | 1.0 | ≥ 0 | ⛔ Ф2 |
🔧 Зарезервировано:
ResourceRegen(пассивный реген ресурса/сек) — добавим при проработке типов ресурса. Способ восстановления зависит от типа (мана регенит по времени, ярость копится от боя и т.п.).
📝 Подумать позже: уровни юнитов в бою (XP/Level). Сейчас прогрессия — только между боями (реликвии/перки), стата Level нет. Макс не уверен — решение отложено.
Фаза 1 реализует 19 статов (авто-атаки без эффектов/способностей/ресурсов): все из §3.1 кроме HealShieldTakenEff; из §3.2 кроме AbilityPower; обе §3.4; обе §3.5.
4. Пайплайн урона (детерминированный)
raw (автоатака = AutoAttackDamage; способность = ScalableValue, Фаза 2)
→ × Source.DamageDealtEff
→ митигация (ПРОПУСК, если DamageType = True):
effArmor = Armor × (1 − PenPct) − PenFlat // % затем плоское
если effArmor ≥ 0: mult = K / (K + effArmor) // K — armor-константа из StatsConfig (старт 100)
иначе: mult = 2 − K / (K − effArmor) // отрицательная броня усиливает урон, ограниченно
dmg ×= mult
→ × Target.DamageTakenEff
→ поглощение Shield → вычет из HP
→ эмит OnDamageDealt / OnDamageTaken (вампиризм/шипы — Фаза 2)
- Физ ветка:
PhysArmor/PhysPen/PhysPenPct. Маг ветка:MagicArmor/MagicPen/MagicPenPct. True: митигация пропускается. K(armor-константа) — поле вStatsConfig, старт100(броня 100 → 50% снижения). Тюнится при балансе.- Отрицательная броня (шред ниже 0) усиливает урон по симметричной ограниченной формуле — деление у нуля не ломается.
- Без RNG — крита и уклонения нет, путь полностью детерминирован.
5. Две семьи множителей: ПОТЕНЦИЯ vs ДЛИТЕЛЬНОСТЬ
Ключевое разделение, не путать (исправляет раннюю формулировку 6. Боевая модель §5.2).
| Семья | Что масштабирует | Исходящая | Получаемая |
|---|---|---|---|
| Потенция (величина числа) | урон | DamageDealtEff | DamageTakenEff |
| исцеление / щиты | HealShieldDealtEff | HealShieldTakenEff | |
| Длительность (время таймированного эффекта) | негатив | ApplyDebuffEff | ReceiveDebuffEff |
| позитив | ApplyBuffEff | ReceiveBuffEff |
- Четыре эфф-эффекта (
Apply*/Receive*) масштабируют ТОЛЬКО длительность таймированного эффекта, НЕ его силу.длительность = base × Source.ApplyEff[polarity] × Target.ReceiveEff[polarity]. ReceiveDebuffEffскейлит и длительность контроля → роль tenacity, отдельного стата не нужно.- Потенция — отдельно: урон/тик и хил/тик проходят свои потенция-множители (
DamageDealt/TakenEff,HealShieldDealt/TakenEff) +ScalableValueот статов источника (напр.AbilityPower).
5.1 ⚠️ DoT / HoT обязаны масштабироваться от длительности
Периодический эффект задаётся скоростью за секунду (per-tick rate), а НЕ запечённым total.
- «Восстанавливает 160 HP за 5 сек» → rate = 32 HP/сек.
- Длительность выросла до 10 сек (через
Apply/ReceiveBuffEff) → total =32 × 10= 320 HP. Rate тот же, тиков вдвое больше.
Реализация:
- В
RuntimeEffectхранитьratePerSecond(илиtotalBase / baseDuration), не готовый total. - Каждый периодический тик применяет
ratePerSecond × Intervalчерез обычный пайплайн (урон →DamageDealt/TakenEff; хил →HealShieldDealt/TakenEff). - Меняется
RemainingTime→ меняется число тиков → total пересчитывается сам. - Запекать итоговый total при наложении — НЕЛЬЗЯ (сломает масштабирование при изменении длительности).
6. Семантика отдельных статов
| Стат | Деталь |
|---|---|
AttackSpeed | Атак/сек. База на реликвии, бонусы через PercentAdd (как bonus AS в LoL). Мягкий потолок ~2.5/сек, клампится из StatsConfig |
CooldownEff | Множитель на время КД: actualCd = baseCd × CooldownEff. < 1 = быстрее. Снижается отрицательным PercentMult |
Size | (1) визуальный масштаб, (2) радиус тела для расталкивания в движении, (3) досягаемость: «в радиусе» = расстояние центров ≤ AttackRange + радиус_свой + радиус_цели |
Lifesteal | Со всего нанесённого урона (автоатаки + способности) |
ProjectilePierce | Сколько целей снаряд пробивает насквозь (0 = стоп на первой) |
StartResource | Читается один раз при сборке юнита (CurrentResource = StartResource), не пересчитывается тиком |
7. Метаданные стата (Фаза 4 — авторинг)
Предложение: на каждый StatType завести запись-метаданные (SO/таблица) для UI/валидации/локализации:
{ ключ_локализации_EN, ключ_локализации_RU, формат (% / число / ×), дефолт, мин, макс, категория }.
Enum и клампы — сейчас (Фаза 1, в Stats). SO-метаданные — Фаза 4.
Открытые вопросы
- Точные дефолты всех статов в
StatsConfig— баланс (Фаза 4+). ResourceRegenи модель восстановления по типам ресурса.- Уровни в бою (XP/Level) — нужны ли (отложено).
- Детерминированный крит («каждый N-й удар») — вводить ли вообще (отложено).