Решили: четыре величины, которых требовали карточки, сделаны данными, а не новыми механиками: AbilityData._repeatSelfEffects (флаг «повторять self-нагрузку столько же раз, сколько нагрузку на цель»), StoneTitheComponent._healShareOfTaken (доля забранного, уходящая в текущее HP — отдельно от доли, уходящей в максимум), RearStrikeEffectComponent._bonusStacks (сколько РАЗ наложить бонусный эффект за удар в тыл) и пара Rule.BonusPerStack + Rule.MaxBonus в TaggedTargetDamageBonusComponent (прибавка за каждый стак требуемых тегов с потолком на правило).

Почему:

  • Повтор self-нагрузки — флаг, а не второе число. Требование Хранителя углей звучит как «столько же, сколько союзнику», то есть величина у обеих половин ОДНА. Отдельное _selfPayloadRepeats завело бы второго владельца этой величины, и при правке залпа половины разошлись бы молча. Флаг выключен по умолчанию намеренно: щит «Стального вихря» — реактив, который вешается на каст РАЗ и растёт от урона всей нагрузки, и повтор тихо выдал бы Копейщику пять щитов вместо одного.
  • Запас и наполнение «Каменной десятины» — два разных числа. Одно не работает ни в какую сторону: лечить на долю запаса — носитель остаётся почти мёртвым и сделка ему ничего не даёт; поднимать запас на всё забранное — он становится танком чужими телами. Разведение даёт нужное: встаёт на ноги сразу, потолок растёт втрое медленнее. Лечение клампится максимумом, излишек теряется — как и доля, не ушедшая в запас.
  • Число стаков с тыла — «сколько РАЗ», а не «насколько сильно». Сколько стаков даёт одно применение — свойство самого эффекта (StacksPerApplication); продублировать его в компоненте значило бы завести второго владельца силы. Поэтому компонент накладывает эффект в цикле, а не просит у него стаки.
  • Потолок прибавки принадлежит правилу, а не компоненту. У правил разная цена входа («по обмороженному» и «по обмороженному и обездвиженному» — разные условия), поэтому общий кап делал бы слабое правило потолком для сильного. Правила остались альтернативами: берётся сильнейшее подходящее, не сумма.

Грабли: счёт стаков в правиле идёт по любому из требуемых тегов, хотя вход в правило требует все разом — и это не рассогласование, а разные вопросы («правило применимо?» и «насколько глубоко цель обработана?»). Пересечение тегов дало бы Криоманту ноль стаков ровно там, где цель проморожена сильнее всего. Ещё: у StackRule нет значения Additive (есть Stack, Refresh, StackAndRefresh) — компиляция теста поймала это раньше, чем я успела поверить своей памяти.

Владелец правды: AbilityData.cs, AbilitySystem.ApplySelfEffects, StoneTitheComponent.cs, RearStrikeEffectComponent.cs, TaggedTargetDamageBonusComponent.cs; тест DataDrivenPayloadRulesTests (шесть кейсов, включая гвард «без флага self-эффект кладётся один раз»).