Границы дока
Это банк идей подачи, питающий Vision - Visual Direction и столп «Ощущение важнее верности пикселю». Технические детали (какой шейдер, какой пасс, сколько стоит на GPU) приведены справочно, чтобы идея не оказалась невыполнимой; канон реализации — за тех-викой, а не за этим доком. Решено оставить в ГДД 2026-07-26.
Gamefeel-бэклог (тактильно-временной слой)
Каталог тактильного/временно́го фидбэка: hitstop, shake, slowmo, squash, тайм-рампы. Собран ресёрчем 2026-07-18. Идеи (
proposed). Зонтик — Vision - Visual Direction (трек 5). Ядро уже богатое (см. трек 5), здесь — принципы из ресёрча + новые докрутки. Легенда: [новое] / [углубл.] / [принцип].
Принципы (из практиков)
- Blend & layer, no single hero (Vlambeer/Joonas Turner): ни один эффект не «делает» фидбэк — вес удара рождается связкой звук+shake+партиклы+hitstop НА ОДНО событие. Проектировать удар как СЛОЙ, не как один эффект. [принцип] — Nuclear Throne explosions breakdown, Dead Cells «What the F?!».
- Pavlovian reward (Hades): каждый удар — микро-награда; отделять фидбэк-действия игрока от ситуативных cue (у нас игрок не бьёт, но «клиент наблюдает» — награда за наблюдаемый удачный размен). [принцип]
- Feel — цель дизайна звука, не полиш в конце (Turner, GDC): тактильные решения принимаются на этапе дизайна события, а не «подмешиваются» потом. [принцип]
Каталог (новые докрутки поверх записанного трека 5)
| Приём | Что даёт | Реализация | Статус |
|---|---|---|---|
| Layered impact «one event → N слоёв» | Единая точка, где на боевое событие сходятся shake+flash+партиклы+hitstop+звук | CombatFeelDirector/CombatPresenter оркестрация | [углубл.] |
| Directional hit-nudge | Цель на хитстопе уезжает от удара и возвращается | LitMotion (unscaled) | [углубл.] (в треке 5) |
| Tiered hitstop по урону | Крупный удар морозит дольше | CombatFeelConfig кривая | [углубл.] (в треке 5) |
| First-blood / last-enemy тайм-рампы | Акцент на первую кровь и добивание последнего врага | TimeScaleService Cinematic | [углубл.] (в треке 5) |
| Anticipation-замах + attacker lunge | Микро-оттяг перед ударом + рывок к цели в импакт | LitMotion (unscaled) | [углубл.] (в треке 5) |
| Тир/уровень, вшитый в рамку HP-бара | Идентичность юнита на самом баре (трюк TFT — звёзды в health bar): компактно, узнаётся мгновенно, оставляет место под остальное | HealthBarView + арт рамки/пипов | [новое] отложено 2026-07-31 (реш. 2026-07-31/70), «может и сделаем, но не сейчас» |
| Иконка класса/типа на торце HP-бара | Мгновенное опознание «кто это» в свалке без текста | HealthBarView + арт иконок классов | [новое] отложено 2026-07-31 (реш. 2026-07-31/70), минимализм сейчас, «мб потом добавим» |
Большинство тактильных идей уже занесены в Visual Direction трек 5 (impact-frame, anticipation, lunge, hit-nudge, tiered hitstop, first-blood, last-enemy ramp, trauma-shake, camera-punch). Этот док — их дом-каталог + принципы из ресёрча, без дублей.
Микро-жизнь юнита под плоский/скелетный стиль — приоритет (ресёрч 2026-08-01)
Контекст: пивот арта персонажей на плоский «сторибук» бумажной куклой (
journal-adr2026-08-01/14). Часть приёмов уже занесена в Visual Direction трек 5 (idle-дыхание, facing-flip squash, target-acquire tell, death-anticipation, contact-dust) — здесь не дубль, а приоритизация под мелкие фигуры, видимые издалека, + новое из ресёрча. Всё строится на LitMotion (spring/твины) и событиях удара, что уже есть; сторонние пакеты (Jiggle/AnyPortrait) как зависимость не нужны.
Сквозная HARD-готча: любой процедурный idle/secondary — с per-unit рассинхроном фазы (случайный offset + ±10-15% периода), иначе строй одинаковых юнитов дышит/качается в унисон и выглядит дешевле статики. И весь слой — тумблерный (реестр feel-тумблеров), чтобы гасить на дальней камере и мерить вклад.
| Приём | Tier | Что даёт | Реализация | Заметка |
|---|---|---|---|---|
| idle-дыхание (синус на торс/голову) | S | сильнейший сигнал «живого» за копейки, виден на силуэте издалека | LitMotion loop | уже в треке 5; per-unit фаза |
| procedural hit-reaction (flinch + knockback + squash + flash на событие удара) | S | удар «дошёл» — читаемость боя издалека | LitMotion punch, sim не трогаем | ложится в per-hit презентер |
свет от боевых эффектов (Light2D-пул, короткие твины) + rim-light | S | сочность боя + отделение фигуры от фона; работает на любом масштабе | URP 2D lights, пул источников | стык с visual-direction трек 3 |
| anticipation-замах перед атакой (наклон/присед корня, синхронно windup) | S | различать атакующих в толпе | корневой трансформ (не аниматор) | уже в треке 5 |
| lean по вектору движения + facing-squash на разворот | A | «вес» силуэта, разворот не телепортом | корень, LitMotion | facing-squash в треке 5 |
| secondary на оружии (spring-overshoot угла хвата) | A | меч ощущается весомым, крупное движение видно издалека | spring на точку хвата | новое |
| look-at головой к цели (доворот кости головы) | A | «посмотрел на врага» читается силуэтом | риг-API Aim, 5-15° | зрачок для арены пропустить — доли пикселя не видно |
| vertex-sway плаща/хвоста/ушей + импульс амплитуды от старт/стоп/knockback | A | дешёвая вторичка без spring-рига на каждом юните | vertex-шейдер | новое |
| зрачок (pupil-offset к цели) · моргание · эмоции-свап лица | B | только крупный план: тултип-портрет, зум, экран награды | swap спрайта Eyes / UV-offset | часть Eyes уже отдельная |
| normal maps на частях | B | тонкий объём — заметен на боссах/крупных, на мелких спорно | Sprite-Lit + _NormalMap | сначала tint+rim, нормалки на боссов |
| Live2D-подобная mesh-деформация | C | псевдо-объём — на мелких фигурах не окупается | Spine/AnyPortrait | пропустить для арены |
Реализация живости под лайнарт-юнита (ресёрч 2026-08-02, proposed)
Углубление таблицы выше под конкретный стиль — плоский лайнарт + solid, cut-out части, рыцарь в латах
как первый юнит. Не дубль tier-списка, а КАК это делать. Все материальные ручки кладутся одним куском
в BodyVisualState → BodyShaderIds.Write через шов IUnitBodyVisual (иначе эффект
достанется одной части); триггеры (урон/каст/крит/низкий HP) приходят из боя через MessagePipe, крутит
их LitMotion. Живость — скриптовые твины, НЕ Animator-клипы (тяжёлый Animator на массовке роняет FPS в
разы).
Взгляд — не Lerp, а саккады
Главный рычаг живости и почти бесплатный (глаза — отдельная часть, управление UV-offset зрачка через
MaterialPropertyBlock, ноль лишних draw-call). Плавное следование Lerp даёт «мёртвый следящий лазер».
Живой взгляд:
- Саккады, а не следование: копим рассогласование, при превышении порога — быстрый прыжок за 2-4 кадра (короткий ease-out), между прыжками «залипание». Пороги из академ-ресёрча ~3° вертикаль / ~7° горизонталь — подкрутить на глаз под мелкую фигуру (числа не геймдев-практика).
- Pink-noise (1/f) дрожь поверх позиции зрачка, амплитуда доли пикселя UV — воспринимается как
«натурально», белый шум и чистое следование — нет. Дёшево: заранее сгенерённая кривая по
Time.time. - Кламп эллипсом (глаз шире, чем выше), не квадратом. Мёртвая зона у центра — иначе микро-тик на джиттере цели.
- Глаза ведут — голова догоняет с задержкой ~100-200 мс; на крупном сдвиге взгляда — моргание (gaze-evoked blink).
- На арене несёт доворот ГОЛОВЫ (риг
Aim, ±15-20°) + моргание — зрачковые саккады читаются только крупным планом/портретом (согласуется со строкой tier-таблицы «зрачок — B, крупный план»). - Моргание — интервал 2.5-6 с + per-unit фазовый сдвиг (закрытие быстрее открытия); чаще при низком HP.
Металл на латах — маска материала + блик
Самый «дорогой на вид» приём для рыцаря. Плоская серая заливка → латы:
_MaterialMask(secondary-текстура, каналы металл/кожа/ткань, художник красит раз) — основа всего блока. Ложится к существующей маске-по-яркости body-шейдера.- Shine-sweep: бегущая полоса блика по маске металла (
smoothstep(t-w,t,d)-smoothstep(t,t+w,d),t=0→1), одинfloat. Медленно постоянно = жизнь, резкий проезд = крит/парирование. - MatCap по нормали (
matcapUV = normal.xy*0.5+0.5) — «жирный» отблеск, требует нормалей (ниже). - Fresnel-rim (
pow(1-dot(normal,view),k)) — холодный контурный отблеск металла. - Свет по металлу (узкий specular + холодный rim) vs коже (мягкий diffuse + тёплый fake-SSS) — через ту же маску.
Свет по плоскому лайнарту — готча контура
- Нормали генерить по ЗАЛИВКЕ БЕЗ чёрного контура (Laigter/SpriteIlluminator), контур накладывать плоским слоем поверх освещённого. Иначе авто-генератор делает обрывы нормали на контуре и металл ловит грязные блики по линии.
- Rim-light — отдельный
Light2Dна Sorting Layer юнитов, Shadows off; вырезает фигуру из фона. - Фейковый AO в стыках (рука за торс, голова в шлем) — художник кладёт тёмный градиент в заливку
part, не через свет.
ShadowCaster2Dна составном теле НЕ ставить — даст щели между слоями. - Нормали подключаются через Secondary Textures спрайта (
_NormalMap), работают со всеми 2D-светами кроме Global.
Живой контур — «рукотворность» сторибука
- Line boil: микро-дрожание/смещение контура на 2-3 состояния (как «кипит» рисованная мультипликация), рассинхрон по юнитам обязателен. Vertex-джиттер или UV-варп контурного слоя.
- Динамика контура: толщина/цвет от состояния — толще на пике удара, тёплый подсвет на касте,
красноватый на низком HP (
_OutlineWidth/цвет какfloat-ручки).
Прочее
- Свап-эмоций лица по боевым состояниям поверх стабильного face-DTO: бровь (нейтр/гнев/боль) + веко (норм/прищур/зажмур) + рот + зрачок = 4 маленьких свапа, весь боевой спектр. Приоритетная машина «текущая эмоция» + кросс-фейд альфы, без блендшейпов. Цена в АРТЕ (нарисовать варианты), не в коде.
- Secondary на ВСЕХ болтающихся частях (плюмаж шлема, полы табарда/накидки, ножны) — spring/pendulum на кости, не только оружие. На рыцаре плюмаж/накидка дают 80% ощущения веса.
- Процедурный smear-шейдер на оружии, триггер на фазе удара (растяжка по вектору скорости; рендерить через MeshRenderer, если границы спрайта режут эффект).
Что НЕ делать для боевой фигуры
- Mesh-warp псевдо-3D поворот головы (Live2D-стиль) — расходится с «бумажной куклой» и face-DTO (голова стабильна, копия неотличима), на мелком юните не читается. Приберечь максимум для крупного портрета в диалоге.
- Тяжёлые Animator-графы на каждом юните — держать живость на LitMotion + шейдере.
Приоритет внедрения (прирост/цена)
- Взгляд (саккады + pink-noise + эллипс + мёртвая зона + моргание рассинхрон) — почти даром, отсюда.
- Динамика контура + line boil + дыхание — копеечные ручки поверх шейдера/LitMotion.
- Shine-sweep +
_MaterialMask— латы оживают. - Look-at головой + secondary на плюмаже/накидке.
- Нормали (по заливке без контура) + rim + MatCap-металл — «финишный лак», ловит свет эффектов.
- Свап-эмоции лица (цена в арте).
- Smear оружия — по вкусу.
Процедурные применения — отложенное (разбор 2026-08-02)
Разбор проекта под правило трёх полос (Code Standards §8: считаем поверхности и формы, собираем из авторских частей по сиду, рисуем руками смысл). Пол арены из этого разбора взят в работу сразу и здесь не дублируется; ниже — то, что осознанно отложено.
Normal-map спрайтов — своим цехом, не руками во внешнем туле
Выше (§«Свет по плоскому лайнарту») записано, КАК нормали должны выглядеть — по заливке без чёрного контура. Здесь — чем их делать: не разовым прогоном через Laigter/SpriteIlluminator, а нашим запекателем, тем же, что печёт фактуры панелей. Причина ровно та, из-за которой у нас появился запекатель: ручной прогон не переживает смену стиля, а тул перепекает весь набор одной кнопкой.
Даёт 2D-свет на плоском арте без единого рисованного канала — из всего осмотренного это меняет картинку сильнее прочего.
Отложено сознательно, причина от Макса (02.08.2026): «Normal map обязателньо сделаем, но не сейчас. Я пока еще в поиске стиля наших юнитов». Нормали настраиваются ПОД конкретный стиль заливки и контура; сделанные раньше выбора, они переделываются целиком. То же основание, по которому отложен весь блок «живость под лайнарт-юнита» выше.
Герб гильдии — средняя полоса в чистом виде
Единственный кандидат на «собираем» из найденных: поле, деление, фигура и кайма рисуются человеком
по разу, а конкретная гильдия получает свой герб из сида. Потребность уже осознана — в PixelLab
пробовались crest, seal, mascot. Механика и место в игре — за ГДД гильдии, здесь только
визуальная сторона.
Оправа иконок
~85 знаков в Art/UI/Icons-gm взяты из game-icons.net (CC BY 3.0) и
рисовались разными авторами — отсюда разнобой. Процедурная оправа, подложка и состояние
(активна / на кулдауне / истекает) склеили бы набор в одно семейство, не трогая силуэты.
Развилка открыта и живёт в gdd/00-meta/open-forks.md §«Генерировать ли иконки процедурно»;
до вердикта не берём.
Фактуры на поверхности, кроме панелей
Alebardium/UI/Bake Panel Textures умеет пять материалов, а применены они пока только к панелям.
Стол карты, задник меню, подложки экранов — тот же тул и ноль новой работы; вопрос лишь в том,
чтобы дойти руками.
Досье Сосудов
Модель («пул фрагментов плюс шаблон-грамматика») описана в
Run - Procedural Lore, статус draft, кода нет. Самая дешёвая
эмоция в проекте, но это текст, а не картинка — и грамматика обязана быть двуязычной с падежами,
то есть опирается на тот же движок, что запись [kw:id:падеж] в тултипах.
Связи
- Партиклы/шейдеры удара — VFX-бэклог.
- Звуковой слой удара (impact transient/body/tail, DSP на slowmo) — Аудио-бэклог.
- Боевое время (TimeScaleService) — контур
combat-sim; feel только потребляет Cinematic-API.