Статус: 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)

ПолеЗначения
DamageTypePhysical (физ) / Magic (маг) / True (чистый — игнорирует броню)
AttackTypeMelee (ближний, мгновенный) / Ranged (снаряд) / ProjectileAoe (снаряд + AOE в точке попадания) / ProjectilePierce (пробивающий снаряд)
ResourceTypeNone / Mana / Rage / … (типы и их реген — прорабатываются позже)

3. Полный список статов (ровно 30)

Op = «натуральная» операция базы. Все статы могут получать модификаторы любой операции (Flat/PercentAdd/PercentMult).

3.1 Выживаемость

ENRUOpСтартКлампФ1
MaxHPМакс. здоровьеFlat≥ 1
HpRegenFlatРеген HP (число/сек)Flat0≥ 0
HpRegenPctРеген HP (% макс/сек)Flat0≥ 0
PhysArmorФиз. броняFlat0может быть < 0 (см. §4)
MagicArmorМаг. броняFlat0может быть < 0 (см. §4)
DamageTakenEffЭфф. получаемого уронаPercentMult1.0≥ 0 (0 = иммун)
HealShieldTakenEffПолучаемая сила исцеления/щитовPercentMult1.0≥ 0⛔ Ф2

3.2 Атака

ENRUOpСтартКлампФ1
AutoAttackDamageУрон автоатакиFlat≥ 0
AttackSpeedСкорость атаки (атак/сек)PercentAdd[0.1, 2.5] из StatsConfig
AttackRangeДальность атакиFlat≥ 0
AbilityPowerСила навыков (AP)Flat0≥ 0⛔ Ф2
PhysPenФиз. пробивание (плоское)Flat0≥ 0
PhysPenPctФиз. пробивание (%)Flat0[0, 1]
MagicPenМаг. пробивание (плоское)Flat0≥ 0
MagicPenPctМаг. пробивание (%)Flat0[0, 1]
DamageDealtEffЭфф. наносимого уронаPercentMult1.0≥ 0
LifestealВампиризм (% от нанесённого урона)Flat0≥ 0

3.3 Исцеление / щиты

ENRUOpСтартКлампФ1
HealShieldDealtEffИсходящая сила исцеления/щитовPercentMult1.0≥ 0⛔ Ф2

3.4 Снаряд

ENRUOpСтартКлампФ1
ProjectileSpeedСкорость снаряда (ед/сек)Flat> 0
ProjectilePierceПробивание снаряда (кол-во целей)Flat0≥ 0, целое

3.5 Подвижность

ENRUOpСтартКлампФ1
MoveSpeedСкорость передвижения (ед/сек)Flat≥ 0
SizeРазмер юнитаFlat1.0> 0

3.6 Эффективность эффектов

ENRUOpСтартКлампФ1
ApplyBuffEffЭфф. наложения положит. эффектовPercentMult1.0≥ 0⛔ Ф2
ApplyDebuffEffЭфф. наложения негат. эффектовPercentMult1.0≥ 0⛔ Ф2
ReceiveBuffEffЭфф. получаемых положит. эффектовPercentMult1.0≥ 0⛔ Ф2
ReceiveDebuffEffЭфф. получаемых негат. эффектов (= tenacity)PercentMult1.0≥ 0⛔ Ф2
CooldownEffЭфф. перезарядки (× времени КД, < 1 = быстрее)PercentMult1.0> 0⛔ Ф2

3.7 Ресурс (только геройские реликвии)

ENRUOpСтартКлампФ1
MaxResourceМакс. запас ресурсаFlat0≥ 0⛔ Ф2
StartResourceНачальный запас (init-only, читается раз при сборке)Flat0[0, MaxResource]⛔ Ф2
ResourceGainEffЭфф. получения ресурсаPercentMult1.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).

СемьяЧто масштабируетИсходящаяПолучаемая
Потенция (величина числа)уронDamageDealtEffDamageTakenEff
исцеление / щитыHealShieldDealtEffHealShieldTakenEff
Длительность (время таймированного эффекта)негативApplyDebuffEffReceiveDebuffEff
позитивApplyBuffEffReceiveBuffEff
  • Четыре эфф-эффекта (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-й удар») — вводить ли вообще (отложено).