Решили: холодная линия реализована ОДНИМ компонентом (FrostComponent) плюс отдельным эффектом
верхней ступени (FrostStatueComponent), а не тремя эффектами по ступеням. Ради неё в ядро добавлены
два шва: физический ПОДТИП в DamageRequest и наложение эффекта со сроком, посчитанным по ходу боя.
Почему: ступень — не состояние, а ворота: «что включено» решают пороги, «насколько сильно» — то же самое число стаков. Три эффекта означали бы трёх владельцев одного счётчика и обязанность синхронизировать их сход. Статуя вынесена отдельно по другой причине: она несёт СВОЙ контроль, свою длительность и правило Раскола, и обнулять «Изморозь» логично тому, кто закрывает окно.
Подтип урона понадобился, потому что хрупкость статуи (+20%) адресована именно дробящему, а броня подтип не различает — значит нести его должен запрос удара, и он же протаскивается через все пересборки запроса (сплит школ, исходящие бонусы, овертайм), иначе теряется по дороге.
Срок при наложении понадобился из-за интерполяции: обездвиживание растёт от 0.5 до 1.5 секунд вместе
со стаками. Три ассета под три точки кривой были бы тремя владельцами одного числа, а поле
BaseDuration — авторское решение, которое не должно зависеть от состояния цели.
Грабли: обездвиживание отсчитывается от тика наложения «Изморози», а не от входа на вторую
ступень, — у компонента нет места под второй таймер (таймер эффекта занят сходом стаков). Цена:
войдя на ступень, цель ждёт до ближайшей отметки периода. Второе: Раскол гасит статую её же сроком
(EndDuration), а не диспелом, — диспел по тегу контроля унёс бы заодно чужие оглушения на цели, а
адресного снятия у шва ICombatContext нет.
Не реализовано из карточки: хвост уязвимости к льду (+20% ещё две секунды после окна) и скейл числа стаков от AP крио-юнита.
Владелец правды: FrostComponent.cs, FrostStatueComponent.cs, DamageRequest.Subtype,
EffectSystem.ResolveDurationTicks, карточка 20-combat/effects/frost (impl_note).