Язык боевых эффектов
Границы дока. Здесь — как выглядит боевое событие: из каких слоёв собрано, сколько живёт, сколько занимает экрана. Чем красим — Gamefeel - VFX Color; чем рисуем — Gamefeel - Asset Palette; тактильная сторона (hitstop, тряска, slowmo) — Gamefeel - Backlog.
Каркас предложен 2026-07-31 и ждёт вердикта Макса; словарь событий наполняется по мере решений. Принятое отмечается датой прямо в строке.
Зачем этот док
До 31.07.2026 у боевых VFX не было спеки — только цвет. Следствие видно в коде: из семи доступных ролей у событий жила одна, вспышка удара держалась три кадра, а удар, лечение и каст рисовались одной текстурой. Бедность приходит не от размера эффекта, а от того, что событие состоит из одного слоя вместо четырёх.
Внешний канон говорит то же самое двумя голосами: Riot требует различать primary и secondary элементы и не давать слабой атаке выглядеть как ультимативной; Vlambeer формулирует резче — никакой один эффект не «делает» фидбэк, вес удара рождается связкой слоёв на одно событие.
Термины
Заведены 31.07.2026 по прямой жалобе Макса («у нас терминов нет норм, путаюсь»). Дальше в кластере и в коде используются только эти слова.
| Термин | Что это | Живёт |
|---|---|---|
| Форма | главный знак удара: серп, веретено или звезда. Лежит вдоль НАПРАВЛЕНИЯ УДАРА | 4–5 кадров после Hit |
| Ядро | радиальная вспышка в точке попадания; единственный свой параметр — радиус | 3 кадра |
| Искры | частицы, летящие ПРОЧЬ от точки удара | 0.15–0.4 с |
| Порез | красная метка на теле цели — вскрытое; накапливается и остаётся | до заживления хилом |
| Остаток | пыль, дым, след на земле — то, что закрывает событие | 0.4–0.6 с |
| Направление удара | куда шёл клинок в момент касания: перпендикуляр к рычагу «плечо → кончик» | — |
| B | точка попадания; маркер Hit. Середина формы у серпа и веретена, конец у звезды | — |
| Дуга за клинком | VFX-сектор с центром в плече, заметающий пройденный угол. Живёт на strike-фазе ВЗМАХА, до хита | strike + 2 кадра |
| Серп | форма хита вдоль направления удара (см. §Автоатака мили) | 4–5 кадров после Hit |
| Кайма | внешняя часть формы, несущая цвет элемента (способ смешения «ядро и кайма») | вместе с формой |
| Обводка | тёмная граница СНАРУЖИ всей формы, включая кайму. Не красит — перекрывает | вместе с формой |
Слово «разрез» больше не используется — вместо него порез.
Кайма и обводка — разные вещи, и путать их дорого. Кайма живёт ВНУТРИ формы и отвечает на вопрос
«чем ударили»; обводка лежит СНАРУЖИ и отвечает «где кончается знак». В шейдере первая — _RimColor,
вторая — ширина без цвета вовсе.
Форму делает шейдер, а не спрайт (принято 31.07.2026)
Эффекты у нас гладкие и параметрические — форму даёт шейдер, а не спрайтовая текстура. Вердикт Макса: «гладкая форма без спрайтов, чисто шейдеры — это круто, я как раз за неклассический пиксель-арт».
Обоснование пересмотрено 2026-08-06 — вывод не менялся.
Изначально правило стояло на разведении по измерениям: «эффекты гладкие, юнит пиксельный», и главным аргументом было, что пиксельная текстура эффекта конкурирует с пиксельным юнитом за детализацию и проигрывает. Пиксель-арт отменён (
2026-08-01/14), и этой конкуренции больше нет — но правило от этого только окрепло, потому что причина под ним оказалась не единственной.
Почему шейдер, а не спрайт, теперь:
- Юнит и эффект говорят одним языком. Плоский сторибук — solid-заливка, толстый контур, объём от движка; параметрическая форма эффекта живёт в той же гладкости. Отмена пикселя не развела их, а свела: форму персонажа подтянули ровно к той гладкости, которая уже была у света.
- Эффект не претендует на форму — он живёт в яркости. Свечение с артом не спорит, потому что работает другим измерением. Bloom с порогом 1.0 настроен ровно на это.
- Параметрическая форма настраивается, а спрайтовая перерисовывается. Дуга, кольцо, линия берут цвет, толщину и прогресс жизни из данных — за это правило и держимся на практике.
Практическое следствие: спрайтовые листы эффектов нам почти не нужны. Форму даёт Shapes (дуги, кольца, линии — параметрически, любым цветом) и шейдер по спрайту. Спрайт остаётся только там, где нужен характер, который светом не передать.
Четыре роли (proposed)
Любое боевое событие собирается из одних и тех же ролей. Роль отвечает на свой вопрос и не лезет в чужой — иначе слои дублируют друг друга и гасят.
| Роль | На какой вопрос отвечает | Живёт | Масштаб |
|---|---|---|---|
| Ядро | «вот здесь, вот сейчас» | 0.05–0.10 с, пик на первом кадре | 0.3–0.5 H |
| Форма | ЧТО произошло — резануло, выстрелило, вскипело | 0.10–0.15 с | 1.0–1.3 H |
| Осколки | откуда и с какой силой | 0.25–0.35 с | частица 0.1 H, разлёт до 0.8 H |
| Остаток | закрывает след, отпускает взгляд | 0.4–0.6 с, гаснет | 0.5–0.8 H |
H — рост юнита-человека, сегодня ≈ 1 мировая единица (96 px при PPU 100). Масштаб задаётся в долях роста, а не в юнитах: сменится сетка спрайтов — числа переживут.
Форма — та роль, которой у нас нет вовсе. Именно она несёт смысл: дуга читается как «резануло» даже мутной, а мягкое пятно не читается никак, сколько его ни подсвечивай.
Три стадии времени (proposed)
Предчувствие → удар → рассеивание. Мозгу нужно указать, куда смотреть, перегрузить его в ожидаемый момент и дать время обработать. У нас сегодня есть только средняя стадия.
Правило, которое стоит повесить на стену: если эффект кажется длинным — он слишком длинный. Боевые эффекты не задерживаются на экране и не мешают читать следующее событие. Плотность арены — константа (четыре «Сосуда» плюс враги, кооператив её не раздувает), но и в ней щедрость по длительности оплачивается кашей: четыре бойца бьют примерно раз в секунду.
Показ идёт на 30 Гц, поэтому кадр = 33 мс. Роль короче двух кадров не существует: она мигнёт и её не заметят.
Шкала важности
Слабая атака обязана выглядеть иначе, чем добивание. Шкала снизу вверх — та же, что у цвета: автоатака → способность → каст за ману → смерть. Растёт по ней не только яркость, но и число задействованных ролей: рядовому удару хватает ядра и осколков, каст добавляет форму, смерть берёт всё четыре.
Словарь событий
Наполняется по мере решений. Пустая клетка — не «забыли», а «ещё не договорились».
| Событие | Ядро | Форма | Осколки | Остаток | Статус |
|---|---|---|---|---|---|
| Автоатака мили — попадание | вспышка, параметр = радиус | серп по архетипу, вдоль направления удара, старт на кадре Hit | искры от удара | пыль у ног | принято 31.07, направление пересмотрено 06.08 ↓ |
| Автоатака мили — промах | — | — | — | — | принято: только надпись «evade» |
| Уклонение — удар по иллюзии | вспышка на копии | серп по копии, обычным порядком | искры копии | копия расходится рябью | принято 21.08 ↓ |
| Рывок / кувырок / телепорт | — | — | — | густой шлейф: восемь копий разом | принято 21.08 ↓ |
| Блок | вспышка щита золотом, тело молчит | серп, обрывается о щит | искры пополам | — | принято, оба поведения под тумблером |
| Выстрел — вылет | вспышка дула | — | искры дула | — | форма у выстрела одна, на попадании |
| Выстрел — попадание | вспышка | линия-всполох после хита | искры от траектории | — | принято 31.07 |
| Лечение | — | не решено | |||
| Каст за ману | всплеск у тела | — | телеграф — свечение части, принято 31.07 ↓ | ||
| Смерть | вспышка | осколки тела | — | частично (death-shatter) |
Отдельных форм под элементы в словаре не будет — ни строки «огненный удар», ни «ледяной». Форма берётся из способа доставки, элемент приходит цветом.
Искры
Два потока с разным поведением, и различает их не цвет, а движение — так они читаются даже когда оттенки близки:
| Поток | Что говорит | Цвет | Живёт | Движение |
|---|---|---|---|---|
| Быстрые | чем ударили | палитра бьющего | 0.15 с (4–5 кадров) | прочь по вектору, узкий разброс |
| Медленные | что вскрыли | красный | 0.4 с (12 кадров) | шире разброс, падают вниз с гравитацией |
Доля быстрых — около 60%.
Количество идёт пропорцией урону, с потолком. Стартовая формула: 6 + доля_HP × 120, но не больше
48 частиц на удар. Потолок обязателен: без него удар кита превратится в стену.
Щедрость здесь осознанная (Макс, 31.07.2026): искры мелкие и живут доли секунды, поэтому их должно быть много — вдвое больше моей первой оценки. Если в бою окажется кашей, число режется одной строкой.
У блока искры пополам — половина цвета блокирующего, половина цвета атакующего (см. ниже); красных при блоке нет вовсе, потому что тело целое.
Призрачные копии: шлейф и иллюзия (принято 21.08.2026)
Копия — поза тела, замороженная в один момент и гаснущая на месте: тот же силуэт, тот же свет юнита, теряющий прозрачность. Один приём обслуживает два события, и это сделано намеренно — иллюзия и шлейф обязаны читаться как одна и та же магия, а не как два разных фокуса.
Шлейф идёт за намерением, а не за скоростью
Копии тянутся за юнитом, который рванул с места сам: кувырок «Отхода», телепорт «Смещения», рывок способности. За телом, которое унесло чужим толчком, шлейфа нет — иначе отброшенный читался бы как рвущийся вперёд. Длину хвоста задают два числа: как часто снимается копия и сколько она живёт; их частное и есть «сколько копий видно разом».
Шлейф густой: восемь копий разом (принято 21.08.2026). Не цепочка отдельных поз, а почти сплошной
мазок — рывок должен ощущаться магией. Это самая дорогая вариация по рендеру (восемь тел по
шестнадцать частей), поэтому интервал снятия остаётся ручкой в CombatFeelConfig, а не константой:
если рой уклоняющихся начнёт стоить кадров, режется он здесь.
На уклонении удар доводится — по копии
Уклонение больше не показывается пустым местом с надписью «evade». Тело выпадает из точки, а в ней остаётся копия, и удар приходит по ней обычным порядком: ядро, серп своего архетипа, искры. Копия на этом осыпается. Это относится ко всем четырём уклонениям, включая то, при котором тело с места не уходило: удар прошёл сквозь — значит бил по копии.
Копия расходится рябью (принято 21.08.2026): кругами от точки удара, наружу, гаснут. Осколки отвергнуты — это язык СМЕРТИ, и на секунду уклонение читалось бы как «убили». Рябь строится теми же копиями (растущими и гаснущими), а не отдельным префабом колец: иначе шлейф и иллюзия перестают быть одной магией и превращаются в два разных фокуса.
Это исключение из правила «нет контакта — нет серпа», и единственное. Промах по телу по-прежнему не даёт ни серпа, ни ядра, ни пореза: там бить было не по чему. Уклонение — другой случай, у него есть адресат.
Копию не красят вторым цветом
Хвост шлейфа — тот же свет юнита, теряющий прозрачность; иллюзия — он же. Перевод копии в «призрачный голубой» отвергнут по общему правилу цвета: цвет говорит, ЧЕМ ударили и чей это юнит, а «нематериальность» несёт прозрачность и режим голограммы — тот же, которым развоплощается тело в смерти.
Порезы: тело помнит бой (принято 31.07.2026)
Красное — это не брызги, а вскрытое. Эталон: в SAO крови нет, вместо неё светящиеся красные прорехи на аватаре. У нас так же — удар оставляет порез на теле цели.
Порезы накапливаются
Каждое попадание записывает мелкий порез: слабый, но заметный. Их много — значит юнита сильно ранили, и это видно без полосы HP. Порез несёт три вещи: место, вес (доля HP этого удара) и порядок (номер по времени).
Хил заживляет САМЫЕ СТАРЫЕ
Лечение снимает порезы с головы очереди — те, что успели затянуться. Тогда исцеление читается как процесс, а не как мгновенный сброс: тело чинится в том порядке, в каком его ломали.
Порез — гладкая светящаяся линия
Порез рисуется в том же стиле, что весь остальной джус — гладкая светящаяся линия. Дословно (Макс, 31.07.2026): «Как и весь VFX, порезы НЕ в писксель арте, а в нашем SAO стиле». Это снимало возражение про сетку 96 px: тонкий светящийся штрих читается там, где царапина в один пиксель потерялась бы. Направление — по вектору удара.
Заживление пропорционально весу пореза
У пореза есть свой «запас»: столько HP, сколько снял породивший его удар. Хил уменьшает яркость пропорционально — порез на 1000 при лечении на 400 тускнеет на 40%, и так до нуля, после чего исчезает.
Отсюда две вещи бесплатно: мерцания нет (порез не выключается, а гаснет), и лечение читается как процесс — видно, что рану затягивают, а не выключают. Заживление быстрое, но не мгновенное.
Порез от выстрела — та же зазубрина
Дистанционное попадание оставляет порез тем же приёмом, что колющий удар: короткая зазубрина в линию рядом с точкой хита. Отдельного правила у выстрела нет — система остаётся единой.
Порезы — это нарративный HP-бар, и так задумано
Число и яркость порезов складываются в состояние тела: сильно раненый юнит выглядит изрубленным. Это осознанный второй язык про здоровье, диегетичный и в духе эталона.
Одно следствие стоит держать в голове: индикаторов здоровья становится три — полоса, порезы и пульс
на низком HP (LowHpThreshold). Третий после порезов может оказаться избыточным; решать это будем,
когда порезы окажутся в игре.
Цвет — красный у всех
Пока единая система: у любого юнита внутренности красные, включая костяных и конструктов. Разведение по видам (белая костная пыль, каменная крошка, зелёные споры) — возможная будущая правка, но не сейчас: единый цвет проще читать и дешевле держать.
Что это значит инженерно
Порез — это СОСТОЯНИЕ тела, а не событие. Он живёт не в пуле эффектов, а в
BodyVisualState через шов IUnitBodyVisual, рядом с тинтом и вспышкой. Отсюда три следствия:
- Лимит списка: 12 порезов (диапазон Макса 8–12, взят верх — откат до 8 это одно число). Шейдер тела получает список: позиция, угол, длина, яркость. Порезы очень мелкие, поэтому дюжина читается как «изрублен», а не как шум; моя первая оценка в шесть была занижена. Сверх лимита старые вытесняются, что совпадает с логикой заживления и потому не выглядит обрезкой.
- Позиции — из
IRngService. Порез живёт долго и виден всем; случайное место, взятое изRandom, разошлось бы между клиентами в кооперативе. - Порез рисуется тем же направлением, что и форма — вдоль вектора удара. Форма прошла, порез остался: одно движение, а не два несвязанных эффекта.
Блок вскрытия не даёт
Щит принял удар, тело целое — пореза нет. Вместо него искры пополам: половина цвета блокирующего (его щит), половина цвета атакующего (его удар). Так в одном событии видно обе стороны размена.
Открытые вопросы события
| # | Вопрос | Состояние |
|---|---|---|
| 1 | Блок: обрыв формы или проход насквозь | оба за тумблером, по умолчанию обрыв; выбор после проверки в игре |
| 2 | Три отложенных способа смешения цветов (вдоль формы, поперёк толщины, слоями) | не отвергнуты; берём «ядро и кайма», остальные лежат в стенде |
| 3 | Искры — количество, срок жизни, красные как кровь по эталону SAO | следующая тема разбора |
Автоатака мили (принято 31.07.2026)
Два эффекта в разное время: дуга на взмахе, серп на хите
Удар показывается двумя стадиями, и это снимает конфликт, который иначе пришлось бы решать иерархией: дуга и серп никогда не видны одновременно.
| Стадия | Что рисуется | Когда | Кому принадлежит |
|---|---|---|---|
| 1 · Взмах | дуга за клинком — сектор с центром в плече, заметающий пройденный угол | strike-фаза, ДО хита | движению оружия |
| 2 · Хит | серп вдоль направления удара, ядро, искры, порез | от кадра Hit | состоявшемуся удару |
Нет контакта — нет СЕРПА (Макс, 31.07.2026). Дуга при этом есть всегда, когда клинок махнул: на промахе видно дугу «в пустоту» и надпись «evade», а серпа, ядра и пореза нет. Серп — заявление «удар состоялся», и на промахе он был бы ложью; дуга же говорит только «клинок прошёл здесь», и это правда даже при промахе.
| Исход | Дуга (взмах) | Серп | Ядро и искры | Порез |
|---|---|---|---|---|
| Попадание | есть | есть, проходит насквозь | есть | есть |
| Блок | есть | есть, обрывается о щит | искры пополам | нет |
| Промах / уклонение | есть | нет | нет | нет |
| Холостой замах | есть | нет | нет | нет |
Форма появляется ПОСЛЕ хита — сразу как нанесён урон, не раньше (Макс, 31.07.2026). Она быстро прорастает от A к концу за пару кадров и гаснет; общая жизнь та же, 4–5 кадров, но целиком после момента контакта.
Отсюда два следствия, и оба удобные:
- Вопрос «а что если промах» решается сам. К моменту старта формы результат уже наступил, поэтому ничего не нужно ни предсказывать, ни стирать. Окно опережения ленты боя здесь не участвует.
- Маркер
StrikeStartформе больше не нужен вовсе (06.08.2026). Он остался у дуги за клинком, которая живёт на взмахе; знак удара берёт направление из позы в момент касания.
Блок обрывает форму — под тумблером
Заблокированный удар в тело не вошёл, поэтому форма тормозит в точке контакта вместо прохода насквозь: точка хита у неё становится конечной, как у дробящего. Тогда «пробил / не пробил» читается самой формой, а не только цветом вспышки.
Оба поведения живут за тумблером и сравниваются в бою: обрыв о щит либо обычный проход насквозь. Решение по умолчанию — обрыв; окончательный выбор после проверки в игре.
Серия ударов: сколько маркеров — столько форм
Атака из нескольких Ударов рисует форму на каждый контакт. Особого рисунка серии не требуется: у таких атак урон на удар мелкий, а размер формы идёт от урона — фигуры получатся мелкими сами, без отдельного правила.
Форма замирает вместе с hitstop
Hitstop морозит пару «источник плюс цель» — форма встаёт вместе с ними, а не проскакивает мимо остановленного времени. Удар залипает в воздухе на кадр, и это работает в пользу веса.
Серп лежит вдоль НАПРАВЛЕНИЯ УДАРА (пересмотрено 2026-08-06)
Знак говорит, КУДА рубанули. Направление — то, куда двигался кончик оружия в момент касания; точка попадания лежит в его середине, а длину несёт урон.
Что здесь было до 06.08.2026 и почему отменено
Серп строился по двум точкам: A — кончик оружия на кадре
StrikeStart, B — точка попадания. Замер живого префаба показал, чем это кончилось: A лежит за спиной и выше (−0.71, +0.90), цель стоит впереди на два с лишним корпуса, поэтому хорда наклонена всего на ~20° — рубящий удар читался лежачей полосой, тогда как клинок в момент касания идёт вниз под ~75°. Вдобавок длина бралась по длине хорды и выходила в полтора роста юнита (2.48 при H = 1.6).Отменено целиком: направление и длина больше не зависят от того, где стояла цель.
Слой ровно один. Прежняя связка «мазок поперёк + дуга от плеча» отменена ещё 31.07: у неё было два разных центра, из-за чего понадобилась иерархия primary/secondary — с одним направлением центр один и проблема исчезает вместе с иерархией.
Направление ЗАМЕРЯЕТСЯ ПО КЛИПУ, один раз при инициализации вида. Два сэмпла вокруг кадра контакта: где кончик оружия был чуть раньше и чуть позже; разница и есть движение. Замер хранится в координатах корня тела, поэтому поворот и зеркало приходят даром.
Позу в момент удара спрашивать НЕЛЬЗЯ
Полдня 06.08.2026 направление считалось из позы — перпендикуляр к рычагу «плечо → кончик». Это оказалось приближением вдвойне. Рука не совсем жёсткий рычаг (длина гуляет на 8% между началом взмаха и контактом), но хуже другое: событие урона приходит раньше, чем Animator применит позу. Презентер тикает с
[DefaultExecutionOrder(-100)], то есть до видов, а поза встаёт вообще междуUpdateиLateUpdate. Спросив кости в этот момент, читаешь прошлый кадр: на медленной атаке 15–20° ошибки, на быстрой — 60–100°, потому что взмах в 200° укладывается там в два-три кадра.Дуга за клинком живёт весь взмах и потому просто читает геометрию в
LateUpdate. Форме такой возможности нет — она рождается по событию, значит опираться может только на замер.
Фолбэка нет. Нет тела, оружия или плеча — формы не будет, а в консоли будет причина (Макс, 06.08.2026: «давай без легаси все же. Просто ругань»). Прежний путь «строим от корпуса бьющего» рисовал знак наугад и выдавал догадку показа за замысел.
| Что | Значение |
|---|---|
| Опора | точка попадания плюс направление удара |
| Форма | дуга через B с прогибом; прогиб — параметр, а не следствие анимации |
| Живёт | 4-5 кадров, начинается НА кадре Hit и целиком после него |
| Толщина | ~0.09 H у середины, сужается к обоим концам |
| Где | в мире, не едет за бьющим |
| Размер, протяжённость, толщина | от урона |
Точка хита лежит в СЕРЕДИНЕ формы, а не в её конце — у серпа и у веретена (Макс, 31.07.2026). Клинок не встаёт в теле: он проходит навылет, поэтому форма продолжается за B на столько же, на сколько шла до неё. Серп разваливает цель по диагонали насквозь, веретено протыкает центрально. Исключение одно — дробящий: у него точка хита КОНЕЧНАЯ, булава там и остаётся, а дальше идёт звезда.
Это не косметика: форма, кончающаяся ровно на цели, читается как «дотянулся», а проходящая насквозь — как «рассёк». Первая версия стенда ошибалась именно здесь.
Почему не трассировка пути клинка: путь зависит от клипа, а клипы у юнитов разные и правятся. Две точки — контракт, который переживёт перерисовку анимации, и его можно посчитать без сэмплирования кривой.
Трейл клинка отклонён — как более слабая версия дуги за клинком (формулировка Макса). Дугу же берём: она рисует пройденный угол сектором от плеча и живёт только на strike-фазе, поэтому в постоянное свечение не превращается.
Три архетипа — это ПРАВИЛА ГЕНЕРАЦИИ, а не три готовых знака
HARD (Макс, 31.07.2026). Режущий — не один и тот же серп на каждый удар, а семейство серпов по правилу. Форма процедурна: каждый удар рисует свой знак, но правило гарантирует, что он читается как «резануло», а не как что-то новое.
| Архетип | Правило генерации | Точка хита | Что остаётся постоянным |
|---|---|---|---|
| Режущий | дуга через B, прогиб и толщина в коридоре, ядро вдоль всей длины | центр | закруглённость и то, что это одна непрерывная полоса насквозь |
| Колющий | почти прямая через B, узкая, ядро у точки входа | центр | прямизна и центральный прокол |
| Дробящий | слабый короткий серп до B плюс звезда в B | конец | движение мягкое, а вспышка-трещина в конце обязательна |
Дробящий, таким образом, двухчастный: булава ведёт лёгкий след и раскалывает в момент контакта. Звезда — 7–9 лучей неравной длины, внутренний радиус растёт, лучи рвутся от центра, как стекло.
Что процедурность НЕ трогает: размер несёт вес удара, поэтому генератор не вправе его менять. Гуляют прогиб, толщина в коридоре, неровность краёв, число и длина лучей у звезды.
Откуда берётся архетип (принято 2026-08-01)
HARD: из данных юнита, и никогда из дефолта. Источников ровно два, оба в его SO:
| Кто бьёт | Откуда архетип |
|---|---|
| дальний бой | из AttackType.Ranged: форма одна на всех — линия-всполох. Тип урона не спрашивается вовсе: у стрелы нет взмаха, и серп ей не положен, даже когда она режущая |
| ближний бой | из типа урона — но лишь потому, что три физических типа ПРЯМО называют способ доставки: рубанули, укололи, ударили тяжёлым |
| безоружный | дробящий: кулак это тяжёлое, а не острое |
Дословно (Макс, 01.08.2026): «Никакого дефолта. Только явное указание (или по типу из SO)».
Почему запрет жёсткий. Школа урона не равна способу доставки: «ледяной удар» не говорит, посохом
бьют или когтем. Подставленный по умолчанию серп — догадка показа, выданная за замысел; невыразимый
случай обязан падать тестом (HitFormCoverageTests) до боя, а не рисоваться наугад. Магический
ближник, когда появится, объявит свой архетип полем в UnitData — отдельным решением, а не веткой в
коде.
Числа
Все линейные размеры — в долях H (рост юнита-человека) и растут пропорционально урону. Категорий «лёгкий» и «тяжёлый» нет: есть непрерывная зависимость от доли снятого HP — и потолок, иначе кит на десять тысяч урона выдал бы стену вместо эффекта. Протяжённость, толщина и радиус звезды едут вместе, сохраняя пропорции: крупнее выглядит сильнее, а не иначе.
| Архетип | Полная длина | Прогиб | Полутолщина в середине | Прочее |
|---|---|---|---|---|
| Режущий | 1.4 H (по 0.7 H в каждую сторону от точки попадания) | 0.20–0.28 H | 0.055–0.075 H | соотношение ~1:12 — росчерк, а не лента |
| Колющий | 1.1 H | 0.015–0.035 H | 0.028–0.036 H | ~1:18, заметно тоньше режущего |
| Дробящий | 0.5 H до B | 0.09–0.14 H | 0.048–0.066 H | звезда радиусом 0.35 H, 7–9 лучей |
| Линия-всполох | вся дистанция выстрела | 0 | 0.024–0.032 H | длина не нормируется: она и есть сообщение |
Толщина сужается к обоим остриям до нуля — форма читается как лист с заострёнными концами, а не как полоса постоянной ширины. Ядро (белый пересвет) занимает внутренние ~55% толщины.
Числа — стартовые, назначены по пропорции и ждут приёмки глазами в play-mode; коридоры разброса заданы так, чтобы два удара подряд отличались, но архетип не терялся.
Форма — параметрическая, и рисуем её сами
Серп рисуется шейдером на одном quad, а не спрайтом и не стеком геометрии. Форма считается в пикселе (SDF), а точки A и B, прогиб, толщина, число лучей, мягкость ядра и прогресс жизни приходят юниформами. Стек Shapes-мешей дал бы плоскую заливку без свечёного ядра и лишние draw call’ы.
Форму обводит чёрный контур (принято 2026-08-05)
Снаружи у формы есть тёмная граница постоянной ширины. Причина — не мода на комикс: арт персонажей ушёл в плоский сторибук с толстым лайнартом, и бесконтурное свечение осталось единственным на экране, у чего границы нет вовсе. Обводка возвращает эффекту край, не отнимая у него яркости.
Разведение осей цело. «Юнит держит форму, эффект держит яркость» работает по-прежнему: обводка не красит, а перекрывает, и её вклад в цвет ровно нулевой. Владельца цвета она не заводит и палитру не трогает.
| Что | Правило |
|---|---|
| Ширина | постоянная, в долях H; на остриях контур смыкается и потому их слегка притупляет |
| Цвет | чёрный, и это не ступень палитры, а отсутствие света |
| Рванность | своя не нужна: обводка строится по маске формы и наследует её неровность краёв |
| Кому положена | только форме удара. Дуге за клинком, свечению части, искрам и ядру — нет |
| Блендинг | premultiplied alpha: аддитив темнеть не умеет в принципе |
Почему не всем. Свечение каста — это свет, а не знак: на теле юнита обводка встала бы вторым контуром поверх лайна самого арта. Зоны на земле и купол барьера — кандидаты, но отдельным решением. Дуга за клинком тёмный край получила, но ДРУГИМ приёмом — см. следующий раздел.
След клинка — росчерк: тёмное живёт внутри градиента (принято 2026-08-06)
У дуги обводки снаружи нет и не будет. Она не знак, а след: хвост у неё гаснет по углу, и контур поверх обводил бы место, где свечения уже нет. Тёмный край здесь — крайняя ступень собственного градиента следа, и лайн получается тем же приёмом, что цвет.
| Ось | Правило |
|---|---|
| Поперёк | пересвет в середине → цвет к краям → чёрная кромка снаружи. Та же ось «ядро и кайма», что у формы |
| Кромка | съедает толщину ИЗНУТРИ: габарит следа не меняется, меняется доля, оставшаяся свету |
| Вдоль | ширина идёт полумесяцем: у хвоста ноль, к клинку — сужена, но жива |
| Хвост | сужение УСКОРЯЕТСЯ к концу (показатель профиля ниже единицы, принято 0.55) |
| Передний край | открыт: там пик света, тёмного торца нет |
Хвост уходит в чёрное сам — там ширина уже нулевая, и отдельного правила ему не нужно.
Эталон — кадр из Cult of the Lamb (00-meta/qa-notes): в середине пересвет, к краям цвет, форма
полумесяцем, а не веером. До этого решения дуга рисовалась одним плоским цветом без ядра вовсе.
Чего пока нет: рванности. Неровность краёв у следа не заведена — у формы удара она есть и детерминирована сидом, здесь это отдельная работа.
Приём кажется бесплатным, но цена та же, что у формы: чёрное перекрывает, а сложение перекрывать не умеет — шейдер дуги тоже стоит на premultiplied alpha. При выключенной подаче он ведёт себя ровно как прежний аддитив.
Что проверено в свалке. Восемь одновременных ударов с обводкой читаются ЛУЧШЕ, чем без неё:
контуры не складываются в грязь, а разделяют формы, которые иначе сливаются в белое пятно. Стенды —
Лаборатория, #/lineart.
Две готчи реализации: quad натянут на форму, поэтому контур наружу требует запаса длины, а bloom с порогом 1.0 растекается с ядра и подъедает тонкую обводку — в игре она обязана быть толще, чем кажется правильным на статичном превью.
Дальний бой: линия-всполох — та же семья, только прямая
Дистанционной атаке серп не нужен, потому что у выстрела нет взмаха: рисовать ему дугу значило бы придумывать движение, которого не было. Ей достаточно линии-всполоха, и это тот же процедурный колющий, просто с нулевым прогибом.
| Что | Значение |
|---|---|
| A | откуда пришёл снаряд |
| B | точка попадания, в середине формы — снаряд идёт навылет |
| Когда | после хита, не в полёте |
| Прогиб | ноль: снаряд летел прямо |
| Работа | ответить «откуда прилетело» плюс общий эффект удара |
Единая система на весь бой: и мили, и дальний строятся по двум точкам с прогибом. У серпа прогиб большой, у колющего почти ноль, у линии-всполоха ноль. Разница в числах, а не в коде.
«Мимо брони» отдельного показа не требует
Вопрос закрыт (Макс, 31.07.2026): по самой атаке видно, что это было. Снаряд света читается как снаряд, удар света в ближнем бою — как один из трёх архетипов. Отдельная форма для Света, Тьмы и Чистого не заводится, предложение «эффект проступает внутри силуэта» снято.
Показ эффектов-способностей (не автоатак) — отдельная будущая тема, и заходить в неё рано.
Формы под элементы НЕ заводятся
Магии, огню, льду и прочему отдельные формы не нужны (вердикт Макса 31.07.2026). Прежнее предложение — восемь форм по двум осям — отклонено целиком.
Причина в разделении осей: форма говорит, КАК доставили, цвет говорит, ЧЕМ ударили. В ближнем бою всегда есть физическая составляющая или понимание, в какой из трёх архетипов удар подставить; в дальнем — линия-всполох. Элемент несёт цвет юнита, и это работает потому, что юнит тематичен: Криомант ледяной именно потому, что он Криомант.
Выигрыш измеримый: матрица покрывается умножением, а не перечислением. Серп × оранжевый — огненный меч, серп × голубой — ледяной. Новый элемент стоит одну строку палитры, а не новый эффект.
Гибриды (юнит с несколькими стихиями) получают цвет на элемент, а не один на юнита; удар, сочетающий стихию и физику — например огонь плюс режущий — комбинирует два цвета.
Способ смешения — «ядро и кайма» (Макс, 31.07.2026): главный элемент светит в ядре, второй идёт
по краю. Выбран из четырёх нарисованных вариантов потому, что показывает оба цвета одновременно в
одном месте — на форме, живущей четыре кадра, это надёжнее градиента вдоль. Остальные три (вдоль
формы, поперёк толщины, слоями) не отвергнуты, а отложены: разбор и живые примеры — в стенде
docs/gamefeel-demos/ §Гибриды.
Ядро всегда остаётся белым пересветом. Раскрасить его значит потушить оба элемента: самое яркое место перестанет быть самым ярким.
Ядро попадания
Радиальная вспышка, у которой единственный собственный параметр — радиус. Своей формы по архетипу у неё нет: форму несёт серп, а ядро отвечает за «вот здесь». Цвета — те же, что у атаки, и тем же способом смешения (ядро и кайма).
Магия мазка не получает ни в каком виде. У магического, светового и тёмного урона нет клинка, которым машут; «след лезвия» для них враньё. Им нужна своя форма — кольцо, всплеск, луч, и это отдельная строка словаря.
Чем управляется каждый параметр
| Параметр | Источник | Почему именно он |
|---|---|---|
| наклон и направление | вектор «атакующий → точка попадания» | тот же, что выбирает точку в области: убийца со спины и копейщик снизу дают разные мазки бесплатно |
| архетип формы | тип урона | форма сообщает, чем ударили |
| длина и толщина | вес удара (доля HP), EvaluateHitVfxSizeMultiplier | тот же множитель, что у искр |
| цвет | палитра бьющего | решение 30.07, не пересматривается |
| вариация | IRngService, ±10–15% | только угол и кривизна |
Рандом не имеет права спорить с информацией. Размер несёт вес удара — сделай его ещё и случайным, и игрок перестанет читать по нему силу. Разнообразие уже даёт другой канал — точка попадания в области; этого достаточно, чтобы восемь ударов подряд не выглядели штампом.
Границы взмаха приходят из клипа
Окно взмаха — от StrikeStart до StrikeEnd: на нём живёт дуга за клинком. Момент запуска формы —
маркер Hit. Форме сами маркеры больше не нужны (см. §Серп лежит вдоль направления удара).
Имена обязаны различаться: ClipMarkers считает контактами события с именем Hit, и маркер
взмаха, названный так же, сим засчитал бы за лишний удар — то есть за лишний расчёт урона.
Офлайн ту же зону размечает RigSweep по скорости кончика оружия — им и сверяться при авторинге.
Точка попадания — зона, и выбирает её досягаемость (принято 2026-08-06)
Бить в одну точку (HitPoint на груди) значит получить восемь одинаковых вспышек в одном пикселе.
Вместо этого у цели три зоны по вертикали, и у каждой заявленный вес:
| Зона | Якорь в риге | Вес |
|---|---|---|
| голова, шея, щека | Aim_Head на кости головы | 5% |
| корпус | Aim_Body на кости груди | 80% |
| верх ног | Aim_Legs на кости таза | 15% |
Заявленный вес — это база, а решает досягаемость. Вокруг атакующего строится круг той же
формулой, что и в бою (AttackRange как зазор между поверхностями плюс радиусы тел), вес каждой зоны
множится на долю её накрытия этим кругом в квадрате, и результат нормализуется. Отсюда бесплатно
берётся всё поведение: мечник у великана достаёт только до ног и лупит по ногам; кончиком клинка
изредка достаёт до бедра; стрелок с большим AttackRange накрывает цель целиком и играет по чистым
весам.
Квадрат, а не линейная доля, потому что вес корпуса больше веса ног в шестнадцать раз: линейно корпус
выигрывал даже будучи вчетверо менее доступным. Резкость — ручка ImpactZoneReachSharpness (1–4);
на двойке зоны уравниваются примерно при 33% накрытия корпуса.
Зону выбирает расчётная геометрия, а бьём по живой. Вес считается от долей роста относительно позиции из ленты — одинаково на всех машинах; точка ставится вокруг якоря на кости — чтобы вспышка пришла туда, где часть тела нарисована. Выбор зоны дискретен, и доля кадра разницы в позе перебросила бы удар из корпуса в ногу у одного игрока; место внутри зоны непрерывно, там та же разница невидима.
Из совпадения формул следует гарантия: если бой засчитал удар, ближайшая точка тела достижима. Вырожденный случай (ни одной зоны) поэтому не «фолбэк», а признак поломки — бьём в самую достижимую и громко ругаемся в консоль, по киту и один раз за бой.
Горизонталь: удар приходит в ближнюю к атакующему половину фигуры. Дальний край силуэта запрещён всем, включая стрелков: стрела, прилетевшая в спину при выстреле в лицо, читается как баг. Восемь сторон света рассматривались и отвергнуты — у плоского спрайта нет глубины, а секторы «сверху/снизу» спорили бы с зонами за вертикальную ось.
Разброс внутри зоны берётся из сида удара (HitFormFactory.SeedOf — хеш от участников, тика и
урона), а не из IRngService: тот принадлежит боевому потоку, и показ его дёргать не смеет. По той
же причине позиции для расчёта берутся из ленты показа, а не из трансформов живых вью:
трансформы интерполируются под кадровую частоту и у двух игроков в кооперативе разъедутся.
Прицельные удары навыком (хедшот, подсечка — в том числе в части, недоступные обычной атаке) осмысленны и могут появиться, но в текущий заход не входят.
Свечение части при касте (принято 2026-07-31)
Каст показывается тем, что светится ЧАСТЬ-ИСТОЧНИК приёма. Эталон — SAO: оружие наливается
светом, когда Система распознала приём. У нас так же, но носитель шире оружия: светится то, чем
бьют, — меч, посох, лук, коготь, кулак, нога при пинке, щит при щитовом навыке. Свечение —
короткий всполох на срабатывании навыка, а не постоянное состояние (2026-07-31/17).
Профиль — как у удара, пассив светит как актив
| Носитель | Профиль свечения | Когда |
|---|---|---|
| Актив с cast-time | наливается по кривой за cast-time → пик на кадре выпуска → быстрый спад | заряд каста |
| Актив/пассив мгновенный | всполох: резкий подъём, мягкий спад | момент применения |
| Блок | всполох ЩИТА цветом защиты; тело не вспыхивает вовсе (Макс, 01.08.2026 — отменяет золотую вспышку тела из 2026-07-31/67) | удар поглощён |
| Длительный бафф / аура (марш и пр.) | телеграфа сейчас нет — контур каста снят (2026-07-31/68), развилка в Open Forks | — |
Пассив = активка без маны (2026-07-31/59), поэтому визуально неотличим от актива и своего
профиля не имеет.
Свет не съедает форму (2026-07-31/66): свечение идёт по яркости самого спрайта, а не заливает
площадь ровно, иначе на пике часть теряет грани и читается силуэтом. Доля плоского света — ручка
конфига (CastGlowFlatness).
Цвет — юнита, форма свечения не элементна
Свечение красится UnitData.VfxColor (2026-07-31/62), навык цвет не переопределяет — та же ось,
что у всего боевого VFX: цвет говорит, ЧЕМ ударили, а не свечение. Огненный меч у синего бойца
светится цветом бойца.
Что это значит инженерно
Свечение — СОСТОЯНИЕ тела, а не событие пула — как порез, живёт в BodyVisualState через
IUnitBodyVisual, а не в пуле VFX-префабов. Отсюда:
- Адресуется по РОЛИ части. Части скелета получают роль (оружие / щит / конечность), свечение подсвечивает набор ролей поверх общего состояния тела — надстройка, не второй канал: часть обязана и светиться сама, и вспыхивать со всеми при ударе. По умолчанию светится часть-носитель приёма.
- Emission в шейдере тела, HDR. Свечение живёт в измерении яркости (
2026-07-31/16); пробивает bloom только на HDR ≥ порога — LDR-палитра арта не светится, так и задумано. - Тайминги и кривые — в
CombatFeelConfig, цвет — из палитры юнита, не в feel-SO.
Реализация шва — контур gamefeel-vfx; правда о коде живёт в самом коде.
Статусы: постоянный слой (принято 2026-07-31)
До этого решения статусы в бою были невидимы: существовали только дев-кольца
CombatStatusOverlay по консольной команде. Постоянный эффект нельзя показывать теми же средствами,
что удар: удар живёт четыре кадра и имеет право звенеть, статус висит секундами на восьми телах
разом — значит обязан быть тихим и однозначным одновременно.
Цвет статуса красится СТАТУСОМ, а не бьющим
Ось 2026-07-31/62 («цвет говорит, ЧЕМ ударили») действует на событиях. У состояния ось
разворачивается: игрок читает на теле цели, что с ней происходит, а не кто это сделал. Автор отыгран
раньше — вспышкой и искрами в момент наложения, там палитра бьющего в силе.
Критерий раздела: общий статус — язык боя, уникальный личный эффект — язык персонажа. Эффект,
который носят несколько юнитов (Burn, Poison, Frostbite, Bleed, стан, сон), красится
статусом. Эффект, существующий ровно у одного носителя и являющийся частью его личности
(BlazingBlades, BloodStance, PackInstinct), красится UnitData.VfxColor.
Гард: уникальный эффект, висящий на ЧУЖОМ теле, красится статусом невзирая на уникальность — иначе метка Следопыта и метка Варлока станут двумя разными понятиями вместо одного «помечен». Практически палитрой юнита красятся почти только баффы на себя.
Четыре канала, в канале не больше одного статуса
| Канал | Где живёт | Что держит |
|---|---|---|
| Воля | поза и темп самого тела | стан, сон, заморозка |
| Тело | силуэт и его материал | горение, яд, изморозь, кровотечение, скрытность |
| Снаружи | контур и над головой | щит, метка, усиление |
| Земля | под ногами | замедление, корни |
Каналы не спорят, потому что заняли четыре разных места вокруг силуэта. Воля старше остальных: кто выключен — тактически важнее, чем кто горит, поэтому застанённый горящий уходит горением в четверть яркости. Младшее в канале гасится, а не прячется — выключенный слой читался бы как «эффект слетел».
Различитель — вектор и темп, а не иконка
Движение ловится периферийным зрением раньше цвета и много раньше формы. При тела́х 96 px и статусе, висящем секундами, это единственный надёжный канал.
| Вектор | Читается как |
|---|---|
| вверх, быстро | горит |
| вверх, редко и медленно | отравлен |
| вниз | теряет |
| нулевое | окаменел |
| медленный пульс | выключен, но цел |
| дрожь | выключен и мучается |
| по орбите | помечен извне |
Заморозке нужен не эффект, а отнятие движения. Абсолютный стоп-кадр среди шевелящихся читается быстрее любого голубого свечения и стоит ноль частиц.
Словарь статусов
| Статус | Канал | Приём |
|---|---|---|
| Стан | Воля | поза обвисла, мелкая дрожь, три коротких штриха по орбите над головой |
| Сон | Воля | тело оседает, медленный пульс яркости, редкие точки вверх |
| Заморозка | Воля | анимация в абсолютный стоп, тело белеет к синему, гранёный контур поверх |
| Изморозь | Тело | синий налёт снизу вверх по силуэту, высота = стаки; дошёл до макушки — Заморозка |
| Замедление | Земля | вязкая клякса под ногами, тянется за юнитом |
| Корни | Земля | то же место, форма схватывающая, а не растекающаяся |
| Горение | Тело | языки от контура вверх |
| Угли | — | своего знака нет: больше огненных всполохов на хите, плюс подъём ступени горения (см. ниже) |
| Яды (их много) | Тело + канал функции | род — пузыри вверх и зелёный подтон; дебафф-часть — своим каналом (см. ниже) |
| Кровотечение | Тело | своего знака нет: порция крови = текущий порез (см. ниже) |
| Лечение (HoT) | Снаружи | искры приходят извне к телу: яд выделяет, лечение собирает |
| Антихил | Снаружи | тот же приход внутрь, но искры гаснут на подлёте и осыпаются — «не доходит» |
| Барьер | Снаружи | сфера: почти невидима в покое, светится от поглощённого урона, остаток — трещины (§Барьер) |
| Метка | Снаружи | один знак над головой, медленное вращение |
| Скрытность | Тело | прозрачность и десатурация, контур остаётся |
| Усиление | Снаружи | восходящие штрихи плюс свечение оружия (§Свечение части при касте) |
Эхо-силуэты статусам не принадлежат — они остаются за рывками. Эхо по природе след быстрого движения; приём, означающий и «очень быстро», и «очень медленно», не означает ничего. Плюс замедленный юнит, стоящий на месте, эха не даёт вовсе — а слоу застаёт его чаще всего именно так.
Точность живёт в отдельном слое, и он тумблер
Постоянный слой отвечает «что происходит и насколько плохо». Точное число стаков и длительность —
информационный слой по клавише Z: тумблер, а не удержание, и пауза его сама не включает —
пауза у нас ещё и кадр, чтобы разглядеть бой. Иначе иконочная ёлка возвращается через постоянно
включённый слой.
Различитель заводится под разницу в ПОСЛЕДСТВИЯХ (принято 2026-08-01)
У нас нет одного «яда». Яд — это статус-форма «DoT плюс обязательный дебафф», и ядов много: «Гниль» Убийцы шредит броню, «Трупный яд» скелетов замедляет и режет лечение, «Ядовитая печать» копит отложенный взрыв. Показывать их одинаково нельзя, показывать каждый по-своему — тоже: игрок не запомнит десять оттенков зелёного.
Правило: различитель заводится под разницу в последствиях, а не в имени или авторе. Два яда с одинаковой функцией выглядят одинаково — игроку от них одно и то же. Три уровня:
| Уровень | Где живёт | Что несёт |
|---|---|---|
| Род | канал «тело» | «его травят» / «он кровит» — природа, не более |
| Функция дебаффа | канал по смыслу функции | шред брони — контур истончается (защита тает); замедление — земля; антихил — искры не доходят; печать — знак с убывающим сроком |
| Число уникальных ядов | канал «тело» | каждый яд даёт свой источник пузырей; оттенки внутри зелёного. Не косметика: «Взрыв спор» лечит за каждый уникальный яд |
Точный состав — информационный слой по Z.
Топливо показывается через удар, а не знаком на теле
Угли (множитель огненного урона, бессрочны, до 999) своего постоянного знака не имеют. Они проявляются двумя способами:
- больше огненных всполохов на хите, когда по цели бьют огнём — даже если цель не горит, видно, что огненный урон по ней растёт;
- поднимают ступень горения, когда цель горит: ступень несёт опасность, а не счётчик стаков, а горящий с углями действительно опаснее.
Угли и «Изморозь» взаимно вычитаются 1 к 1 — значит на теле почти никогда не видно термальную пару одновременно, и абсурд «горит и обмерзает» решён в механике, а не в шейдере.
Жизнь эффекта: рождение, повтор, конец (принято 2026-08-01)
Шесть событий, которые до этого выглядели одинаково. Главное правило: снятие сохраняет ФОРМУ и меняет только ЦВЕТ — тогда видно и «что» сняли (по форме эффекта), и «чем» (по цвету). Та же ось, что у удара, где форма говорит КАК доставили, а цвет — ЧЕМ ударили.
| Событие | Показ | Что читается |
|---|---|---|
| Наложился | всплеск формы наружу и осадка | эффекта не было, стал |
| Стак +1 | толчок: форма дёргается наружу и возвращается | стало больше |
| Обновили срок | волна по телу, форма не растёт | стало дольше, но не сильнее |
| Клинс | форма голубеет, затем тает | с тебя сняли плохое |
| Диспел баффа | форма темнеет и срывается, без таяния | с тебя сорвали хорошее |
| Истёк сам | ровное угасание в своём цвете | ничего не произошло, время вышло |
Голубой — цвет действия, а не кастера: клинс Пастыря и клинс Друида обязаны читаться одинаково, иначе «сняли» перестанет быть одним понятием. Тот же гард, что у цвета статусов.
Перекраска и растворение идут последовательно, не разом: сначала цвет (2–3 кадра), потом таяние (3–6). Одновременно получилось бы «мигнуло и исчезло», и «что» потерялось бы — ради него приём и заведён.
Истечение не красится ничем. Любой цвет превратил бы его в событие, а оно не событие. Симметрично барьеру: развеивание ровное, разрушение с осколками.
«Не влез в потолок» не показываем вовсе. Глухих потолков у нас почти нет: угли и гниль до 999, кровь без потолка, а двадцатый стак «Изморози» — не отказ, а переход в статую. Наложение сработало, просто иначе, и показывать нечего.
Тик DoT — мягкая волна в цвете школы (принято 2026-08-01)
Постоянный знак получает только тот статус, у кого есть постоянное СОСТОЯНИЕ ТЕЛА: горит — языки, обмёрз — налёт, ранен — порезы. Сам факт «его точит DoT» несёт волна по силуэту в момент тика.
| Волна DoT | Вспышка удара | |
|---|---|---|
| Цвет | школы (яд зелёный, огонь оранжевый, кровь красная) | белая |
| Живёт | ~10 кадров | 3 кадра |
| Характер | мягкая, идёт по телу снизу вверх | резкая, вся разом |
Отсюда ответ на «ядов много»: у яда состояния тела нет — есть тик и дебафф, поэтому постоянного знака ему не полагается вовсе. Все яды дают одну зелёную волну, а различаются дебафф-частью, у которой визуал уже решён (шред брони, замедление, антихил, печать). Десять разных ядов выглядят одинаково ровно потому, что делают для игрока одно и то же.
Кровотечение: порция крови — это текущий порез
Кровь идёт по порционной модели: каждое наложение — своя порция со своей силой и своим сроком, порции сходят независимо, потолка нет, а число стаков — производная от их числа. Ступеней у механики нет, поэтому показ их не назначает:
| Что | Чем показано |
|---|---|
| число ран | число текущих порезов на теле |
| общая сила | ступень по DPS (см. ниже) |
| «Разрыв» тратит порции | порезы гаснут разом, а не по одному |
Своего знака кровотечению не нужно: у пореза и так есть свой запас и своё независимое угасание.
Стадий четыре, и берутся они из DPS-метра крови — механика при этом не меняется вовсе: порции работают как работали, метр только читает их суммарный урон. Пороги — в долях maxHP цели за секунду, а не в абсолютных единицах, которые устареют с ростом статов за забег.
Стадию несёт ПРОПИТЫВАНИЕ (принято 2026-08-01): тело краснеет снизу вверх, на четвёртой стадии залит целиком. Подтон намеренно слабый — «не съедает силуэт, просто чуть красит»: силуэт остаётся носителем класса и оружия, то есть более важного факта.
Работает площадью, а не мелкой графикой, поэтому читается и в свалке из восьми тел, где капли
терялись бы. Отклонены: капли со струйками (мелко), свечение ран (путается с огнём), пульс (требует
смотреть на юнита секунду, а в автобое её нет). Все четыре подхода остались в стенде
docs/gamefeel-demos §Превью эффектов.
Число порезов при этом остаётся вторым, независимым фактом: стадия говорит, как быстро он умирает, порезы — сколько ран открыто.
Стак читается тремя ступенями (принято 2026-07-31)
Постоянный слой сворачивает число стаков в три состояния тела: мало / средне / много. Глаз надёжно различает ровно столько; непрерывная шкала формально честнее к модели, но 17 против 20 в бою не читается, да ещё и упирается в потолок там, где стаки идут дальше. Точное число берёт информационный слой.
Пороги — абсолютные числа на самом статусе, а не формула от потолка. Масштаб стаков у каждого свой, единой формулы на всех не будет; четыре порога живут в SO статуса. Ступени режут не порядок величины, а игровой смысл. У «Изморози» пороги уже заданы механикой — Замёрз (1–9), Примёрз (10–19), Обратился в лёд (20), — и показ берёт их, а не назначает свои.
Шкала огня (это шкала «Углей» плюс факт горения, а не стаков Поджога — у Поджога стаков нет вовсе):
| Ступень | Стаков | Смысл |
|---|---|---|
| 1 · мало | 1–9 | норма |
| 2 · средне | 10–29 | сильно |
| 3 · много | 30–99 | перекачано |
| 4 · пасхалка | 100 и выше | поломка |
Переход между ступенями — кроссфейд 0.15 с, а не переключатель. DoT тикает и добавляется, стаки ходят вокруг порога, и на жёсткой границе тело мигало бы между состояниями.
Четвёртая ступень существует — как пасхалка на сломе, а не как продолжение шкалы. Абсурдный стак не показывается «ещё ярче»: тело меняет состояние — языки сходятся в столб выше роста, тело уходит в силуэт внутри пересвета. Три гарда:
| Гард | Значение |
|---|---|
| Порог | 100 и выше, открыт вверх — 999 это пример, а не граница |
| Где живёт | у эффектов без балансного потолка: где потолок есть, сотня недостижима |
| Частицы | тот же потолок, что у искр — растёт характер, не количество |
В язык читаемости четвёртая ступень не входит: важную информацию на неё вешать нельзя, её почти никто никогда не увидит. Тумблер обязателен, как у любого эффекта джуса.
Барьер: щит, который помнит удары (принято 2026-07-31)
Речь о поглощающем барьере (EffectTag.Shield), не о блоке щитом-предметом — тот решён отдельно
(вспышка золотом, серп обрывается о щит, пореза нет).
Барьер висит постоянно, но в покое почти невидим. Сфера — самая большая площадь из всего, что мы рисуем; постоянная яркая сфера перекрыла бы канал «Тело», и горение с порезами оказались бы за стеклом. Поэтому в покое — еле заметная кайма, а работать барьер начинает под ударом.
| Событие | Показ |
|---|---|
| Удар поглощён | подсветка, тем сильнее, чем больше урон, и сильнее всего в точке контакта |
| Тик эффекта (DoT) | вспышка по всей поверхности, но слабее: бьют не в место, а всюду |
| Остаток барьера | доля проявленного узора трещин (см. ниже) |
| Разрушение (сломали) | трещины сходятся, куски скорлупы уходят радиально прочь от юнита и быстро гаснут по прозрачности |
| Развеивание (истёк) | гаснет ровно, вверх, без осколков |
Два финала обязаны читаться по-разному: «сняли» и «кончился» — разные тактические факты. Различитель — наличие осколков, а не их направление: барьер лопается целиком, а не сдувается в сторону, а кто добил, уже сказано вспышкой в точке контакта кадром раньше.
Трещины — это узор, из которого видна доля
Узор генерируется целиком при рождении щита, показ проявляет его часть — не «восемь трещин», а «от части до всего узора». У порезов на теле дискретность несёт смысл (каждый порез — удар); у барьера смысл другой, «насколько цел», то есть площадь, а не счёт. Счётные трещины упёрлись бы в лимит на двадцатом ударе и перестали показывать разницу.
| Правило | Почему |
|---|---|
| Проявление идёт от точек удара, не по индексу | узор остаётся связным, но помнит, откуда били |
| Геометрия монотонна, яркость = текущая целостность | трещины не заживают, но «вот-вот лопнет» при крепком барьере — ложь. Широкая бледная сеть = «били сильно, сейчас крепок» |
| Полный узор совпадает с пробитием | распад идёт по своим же трещинам, шкала не требует калибровки |
| Узор принадлежит оболочке | развеялась — унесла свой узор; новый щит приходит с чистым |
Оболочка — на тип, вложенность — очередь трат
| Тип | Цвет | Место |
|---|---|---|
| физический | оранжевый | снаружи |
| магический | фиолетовый | под ним |
| обычный | сероватый | ближе к телу, тратится последним |
Оболочка одна на тип, а не на эффект: четыре налёта Антимага дают одну фиолетовую, потому что игроку нужно «магией не пробить», а не «какой из четырёх сейчас тает». Значит оболочек максимум три. Вложенность повторяет очередь трат в симуляции — школьные щиты работают в pre-damage, до вычета общего пула.
Трещины есть только у оболочек, которые реально ели урон: пока внешняя цела, до внутренней урон не доходил. Отсюда и ответ про перегрузку — одновременно треснутых максимум три, на практике одна-две.
Стаки барьеров (Антимаг копит без потолка) идут той же трёхступенчатой шкалой, что стаки статусов — толщиной и плотностью каймы.
Блок — это тот же барьер, только на 0.4 с и с жестом
BlockComponent при срабатывании накладывает короткий щит-эффект, который и гасит вызвавший его удар.
Значит барьер — механизм, а блок — один из способов его получить, и отдельного визуального языка ему не
нужно.
| Живёт | Жест | Будят | Читается как | |
|---|---|---|---|---|
| Блок | 0.4 с — узор не успевает проявиться | есть | только прямые удары, нужна дееспособность | «отбил» |
| Барьер | секунды | нет | всё, включая DoT | «под защитой» |
Жест целится в точку удара — направление берётся оттуда же, откуда точка попадания, поэтому наведение
это базовая поза плюс Aim части-щита.
Блок направленный, барьер — нет (принято 2026-07-31). Блок проверяет фронтальный сектор 180° тем же правилом, что парирование, поэтому удар со спины его не будит вовсе: оболочка не поднимается, урон идёт в тело. Жест от этого становится честным всегда — он есть ровно там, где блок сработал. Барьер направления не знает и гасит что угодно, включая тик яда и удар в спину, просто без жеста.
Жест живёт на верхнем слое анимации и прерывается: заряды блока независимы, два жеста могут пойти подряд и посреди собственного замаха.
Пробитие насквозь — исключение из «формы, обрывающейся о щит»
Щита 20, удар 100: барьер лопнул, 80 ушло в тело. Тогда форма НЕ обрывается и порез есть. Правило целиком: обрывается о щит, который выдержал; проходит сквозь тот, который пробит.
Показу нужен журнал, а не состояние сима. Барьер живёт в презентации, как порезы: сим присылает события (щит поднят — тип и величина · поглощено — тип и сколько · щит ушёл — тип и сколько унёс), а оболочки, узоры и их доли собирает показ. Поэтому порядок трат в симуляции менять не пришлось.
Две связки работают без правок: серп обрывается о барьер так же, как о щит, и пореза нет — «нет вскрытия, нет пореза» распространяется на барьер само собой.
Форма — эллипс: круглая, без углов, просторнее тела
Поверхность круглая — гранёные и стеклянно-фасетные варианты отклонены. Из круглых принят эллипс: вытянутый по высоте симметричный сфероид. Термин канона — купол («конус» не подходит — у конуса вершина; «шар» тоже — в проекции он не круглый).
| Параметр | Значение |
|---|---|
| Полуоси | ~0.34 H в ширину, ~0.68 H в высоту |
| Центр | 0.52 H от земли |
| Низ | подрезан линией земли — купол стоит, а не парит |
| Заливка | почти нулевая: тело под куполом важнее |
Зазор до тела намеренно заметный. Пустое место у барьера — не дефект, а смысл: барьер окружает юнита, а не обводит его. Формы, облегающие силуэт плотнее (овоид с сужением к макушке, кокон с прямыми боками), отклонены именно за это — они читаются как контур тела, а не как силовое поле.
В покое видно только силуэт — тонкую линию контура. Подсветка приходит исключительно с ударом: пятно в точке контакта расходится волной по поверхности, и чем слабее остаточная вспышка, тем шире фронт.
Узор трещин живёт в геометрии купола и задаёт линии разлома, поэтому при пробитии скорлупа расходится кусками именно этой формы. Разбор отклонённых вариантов — Closed Forks.
Что это значит инженерно
Статус — состояние, а не событие пула: живёт в BodyVisualState через IUnitBodyVisual, рядом с
порезом и свечением части. Пул VFX-префабов нужен только на момент наложения. Канал «Земля» —
единственный, кому нужен свой носитель: спрайт/Shapes на слое GroundFX под юнитом.
Реализация шва — контур gamefeel-vfx; правда о коде живёт в самом коде.
Зоны: круг, линия и то, что стоит на арене (proposed, 2026-07-31)
Формы в механике две — круг (вокруг себя либо вокруг цели) и линия (перед юнитом в сторону цели).
Третий вид заведён решением 2026-07-31/93: стоячая зона, живущая на арене и тикающая, — облако
спор, ледяное поле, горящая земля.
Три фазы, акцент на подводке
| Фаза | Что рисуем | Живёт |
|---|---|---|
| Подводка | контур зоны, заполняющийся к моменту срабатывания | cast-time способности |
| Срабатывание | вспышка по контуру и внутрь | 3–4 кадра |
| След | отметина в форме зоны, гаснет | 0.5–1 с |
Акцент на подводке принят сознательно (2026-07-31/94): игрок в автобое не уклоняется, но круг,
растущий под ногами, делает бой читаемым в момент, а не только в разборе. Наш лаг показа делает
подводку честной — сим уже посчитал, лента её держит, круг не врёт о том, что случится.
Инженерное следствие: зональному касту нужен cast-time, иначе подводке негде жить. Мгновенный зональный каст показывает только вспышку и след.
Контур несёт форму, заливка почти отсутствует
Зоны пересекаются, а аддитивные заливки складываются: две зоны дают пятно, три — кашу. Поэтому работает контур, а заливка живёт на минимуме и только внутри срабатывания.
Зона лежит в плоскости земли — круг рисуется эллипсом с той же сплюснутостью, что тень юнита и купол барьера. Иначе он читается как сфера в воздухе.
Цвет — по уже принятому правилу
| Что | Чем красится |
|---|---|
| зона-удар (взрыв, прокол, ледяное поле от врага) | палитра бьющего: это событие |
| зона-аура, зона-бафф по союзникам | цвет статуса: это состояние |
Чем стоячая зона отличается в показе
Она не имеет фазы подводки (её никто не «заряжает» — она уже здесь) и не гаснет по следу: контур держится всё время жизни, а тик по стоящим внутри показывается на телах, а не на земле. Иначе каждый тик перерисовывал бы зону и она мигала бы вместо того, чтобы лежать.
Что здесь НЕ живёт
- Цвет и насыщенность — Gamefeel - VFX Color.
- Какая текстура играет роль — Gamefeel - Asset Palette.
- Hitstop, тряска, slowmo, замедление на добивании — тактильно-временной слой, Gamefeel - Backlog и трек 5 Vision - Visual Direction.
- Как это устроено в коде — шов
VfxData→ префаб → пул → сокет живёт в контуреgamefeel-vfx; правда о реализации — в самом коде. - Идеи без вердикта — Gamefeel - Backlog (Particles & Shaders).