Game feel
Контекст
Термин закрепил Steve Swink в книге «Game Feel» (2008): ощущение управления виртуальным объектом в реальном времени — то, что нельзя свести к правилам, но что игрок чувствует руками. Канонические примеры — Celeste и Mario: их прыжок ощущается «правильным» не из-за формул движения, а из-за десятков подкрученных мелочей вокруг них. Девиз ремесла — «juice it or lose it»: без слоя обратной связи технически корректная механика воспринимается мёртвой.
Ключевая мысль, которую инженер должен принять: то, что делает симуляция, и то, что воспринимает игрок — это две разные вещи, и game feel живёт именно в зазоре между ними.
Механизм
Game feel собирается из двух семейств приёмов: прощение ввода (input forgiveness) и обратная связь (feedback).
Input forgiveness — честность контролей без объяснений
- Coyote time — игроку дают прыгнуть ещё ~5–6 кадров после того, как он сошёл с края платформы. Игрок «знает», что нажал вовремя; код прощает рассинхрон между намерением и реакцией.
- Jump buffering — прыжок, нажатый за несколько кадров до приземления, всё равно срабатывает в момент касания земли. Без буфера ранний ввод теряется, и игра ощущается «глухой».
- Variable jump height — высота прыжка зависит от длительности нажатия: отпустил кнопку рано → срезаем восходящую скорость (прыжок ниже), держишь → выше. Базовый платформенный контроль, который игрок «чувствует пальцем» (есть тумблером в Lab 09).
Обе техники игроку не объясняют — он просто чувствует, что «контроли честные». Это и есть иллюзия честности: поблажка, замаскированная под отзывчивость.
Feedback — продать «вес» и событие
- Hit-stop — заморозка геймплея на пару кадров в момент удара: мозг читает паузу как «масса встретила массу», и удар обретает вес.
- Screen shake — тряска камеры как тактильный акцент на взрыве/попадании.
- Particles — пыль под ногами, искры, брызги: визуальное эхо события.
- Squash-and-stretch — деформация при ускорении/приземлении; первый из 12 принципов анимации Disney, перенесённый в реальное время.
- Camera lerp / lookahead — камера не приклеена жёстко, а догоняет цель с задержкой и смотрит вперёд по движению.
Общий знаменатель всего стека — разведение «что делает симуляция» и «что воспринимает игрок». Симуляция остаётся честной и детерминированной; слой feel живёт поверх неё и врёт ровно настолько, насколько нужно для ощущения.
Математика тайминга
Почему «окно прощения» вообще нужно — считается арифметикой кадров. Бюджет одного кадра при 60 fps:
Время реакции человека — порядка 200 ms. В кадрах это:
То есть между «вижу край» и «палец нажал» проходит около дюжины кадров — поэтому окно прощения порядка ~10+ кадров ощущается не как чит, а как компенсация физиологической задержки игрока.
Вторая базовая формула feel — сглаживание камеры (lerp к цели каждый кадр):
Это удобно, но привязано к частоте кадров: один и тот же k на 30 и 144 Гц даёт разную скорость догона. Frame-rate-independent вариант делает коэффициент функцией dt:
Почему именно так — в хардкоре про математику.
🕹 В какие игры поиграть — и что заметить
Game feel нельзя прочитать — его ловят пальцами. Четыре платформера, от одной базовой ручки до целого стека ощущений; по каждому — что подкручено и что заметить руками (от простого к сложному).
Откуда всё пошло. Высота прыжка зависит от длительности нажатия (держишь — выше, отпустил рано — срезали восходящую скорость) плюс инерция: Марио не стартует и не тормозит мгновенно. Одна-две ручки, но именно они делают управление «вкусным» — без них прыжок мёртвый, с фиксированной высотой.
🎮 Сыграй: любой Mario (хоть SMB, хоть Odyssey). Сделай два прыжка подряд — коротко тапни и зажми кнопку: высота разная (variable jump). Разбегись и резко развернись — Марио проскальзывает по инерции, не клеится к нулю. Вот два самых базовых feel-knob'а.
Эталон современного game feel, задокументированный самим разработчиком (Maddy Thorson). Стек «прощения»: coyote time (прыжок ~0.1 с / ≈6 кадров после схода с края), jump buffering (нажатие до приземления срабатывает в кадр касания) и corner correction (бьёшься головой об угол — игра подвигает тебя вбок мимо него; клипнул угол дэшем — подкидывает на полку). Всё «фуджит» в пользу игрока ровно настолько, чтобы казаться отзывчивым, а не магнитным.
🎮 Сыграй: Celeste (или демо). Прыгни с края заведомо поздно — coyote спасёт. Прыгай впритык к низкому потолку в углу — заметь, как тебя подталкивает мимо угла (corner correction), вместо того чтобы «бонкнуть» и упасть. Включи Assist Mode — увидишь, что игра уже прощает, ассист лишь усиливает.
Обратный полюс: минимум поблажек, максимум отзывчивости. Управление настолько прямое и цепкое (быстрый разгон, липкие стены), что смерть всегда читается как «я сам». Ключ — мгновенный респаун: ноль загрузки между попытками, поэтому feel ощущается на каждой из сотен смертей, а не раз в минуту.
🎮 Сыграй: Super Meat Boy (демо/полная). Умри 20 раз подряд на одном экране и заметь: между смертью и новой попыткой нет паузы — это часть feel, а не UX-мелочь. Прижмись к стене — мгновенное цепкое сцепление и отскок, без «ватного» лага.
Feel выходит за пределы движения — в бой. Удар гвоздём даёт hit-stop (микрозаморозку на контакте → «масса встретила массу») и knockback (отдача толкает и тебя), а удар вниз по врагу или шипе — pogo: отскок вверх, превращающий бой в платформинг. Плюс экранная тряска и частицы. Тот же стек, но на боёвке.
🎮 Сыграй: Hollow Knight (демо). Бей врага в упор — почувствуй микропаузу удара (hit-stop) и отдачу. Прыгни на врага/шипы и бей вниз — отскочишь (pogo); попробуй пропрыгать на гвозде по цепочке шипов. Feel — это не только прыжок.
Хардкор · дизайн: почему forgiveness работает и 12 принципов Disneyможно пропустить
Перцептивная честность: время реакции ~200 ms
Игрок не управляет в реальном времени — он управляет с лагом собственной нервной системы (~200 ms, ~12 кадров на 60 fps). Без прощения каждое «я же нажал!» — это правда: намерение было вовремя, моторика опоздала. Coyote time и jump buffering закрывают разрыв между perceived (когда игрок «решил») и actual (когда пришёл ввод). Отсюда иллюзия честности: игра кажется отзывчивой именно потому, что тайно подыгрывает — но в пределах человеческой задержки, не больше, иначе чувствуется «магнит».
12 принципов Disney в реальном времени
Классическая анимация — готовый словарь feel-приёмов, переложенный на интерактив:
- Squash & stretch — деформация массы при ускорении/приземлении; продаёт упругость и вес.
- Anticipation — микро-замах перед действием (приседание перед прыжком) — глаз успевает «прочитать» намерение.
- Follow-through & overlap — части тела/плаща догоняют корпус после остановки; убирает «робота».
Разница с фильмом: в кино аниматор владеет таймингом, в игре тайминг диктует игрок — поэтому принципы становятся процедурными (squash как функция вертикальной скорости, anticipation как пара кадров перед стартом).
Juice-стек как чеклист
Практический приём: брать сырую механику и прогонять по списку — input forgiveness (coyote, buffer), hit feedback (hit-stop, shake), motion (squash, anticipation, follow-through), ambient (particles, camera lerp/lookahead, sound). Каждый пункт добавляется отдельным тумблером, чтобы можно было выключить и почувствовать вклад (ровно это делает Lab 09).
Хардкор · математика: кадры↔мс и геометрическое затухание камерыможно пропустить
Кадры ↔ миллисекунды
Все feel-тайминги удобнее держать в кадрах, но мерить в миллисекундах (иначе на 144 Гц «6 кадров» — это другое физическое время). Перевод:
Окно прощения ~10 кадров ≈ 167 ms — меньше времени реакции (~200 ms), поэтому компенсирует моторную задержку, не выходя в «читерство». Hit-stop задают как N кадров (типично 2–6): на N кадров замораживается геймплейный тик, удар читается как столкновение масс. Слишком большой N — игра «залипает», слишком малый — эффекта нет.
Lerp как геометрическое затухание
Наивный кадровый lerp p ← p + (target − p)·k за m кадров оставляет ошибку:
Это геометрическая прогрессия: ошибка падает как (1−k)m. Но m — это число кадров, а не время. На 144 Гц за ту же секунду кадров в ~2.4 раза больше, чем на 60 Гц, значит (1−k) применяется в ~2.4 раза чаще — камера догоняет ощутимо быстрее. Один и тот же k → разный feel на 30/60/144 Гц. Это и есть баг наивного lerp.
Frame-rate-independent форма
Чинится переходом к непрерывной модели: затухание — это экспонента от времени, а не от числа шагов. Подставляя реальный dt:
Теперь коэффициент шага зависит от dt, и за одинаковое время ошибка падает одинаково при любой частоте кадров. Тот же приём — для любого экспоненциального сглаживания (damping скорости, фейды), не только камеры.
Хардкор · инженерия: juice без потери детерминизмаможно пропустить
Feel ломает наивный игровой цикл сильнее, чем кажется. Что держать в голове:
- Hit-stop морозит геймплей, но не UI. Заморозка должна останавливать физик-тик/симуляцию, но не презентационный слой: меню, курсор, иногда сами частицы продолжают жить. Если морозить общий timescale, замирает всё, включая интерфейс — выглядит как фриз/баг. Разведи feel-эффекты и симуляционный тик.
- Детерминизм. Coyote/buffer/hit-stop меняют тайминг входов, а в сетевой/replay-игре это часть состояния. Считай окна в кадрах фиксированного тика (а не в реальных секундах), храни счётчики в симуляционном состоянии — иначе replay и netcode разъезжаются. Screen shake и частицы держи чисто на стороне презентации: они не должны влиять на симуляцию.
- Frame-rate-independent тайминг. Все feel-константы — в миллисекундах/секундах, в шаге умножаются на dt (см. хардкор по математике). Тогда game feel одинаков на 30/60/144 Гц. Исключение — фиксированный физик-тик: там кадр стабилен, и окна можно держать прямо в кадрах тика.
- A/B juice-toggle (Lab 09). Архитектурно полезно вынести весь juice за один флаг/слой, чтобы включать-выключать без правки геймплея. Это и тестовый стенд (почувствовать вклад), и страховка детерминизма: если toggle меняет исход симуляции — значит juice протёк в логику, и это баг.
Фронтенд / UX: optimistic UI (показать результат до ответа сервера = тот же jump buffer/coyote), skeleton-экраны, perceived performance, прощение ввода в формах.
ML / AI: стриминг вывода LLM (токены по мере генерации — воспринимаемая латентность падает в разы при той же реальной); «думает…»-индикаторы; вся UX-обвязка вокруг медленных моделей — это game feel для AI-продукта.
Распределённые / сети: latency hiding, prefetch, спекулятивное исполнение — то же «perceived ≠ actual».
Принцип: воспринимаемое ≠ фактическое; инженерь восприятие, а не только систему — и компенсируй задержку человека, не выходя в «магнит».
Почему coyote time ощущается «честным», хотя технически это поблажка игроку?
Почему hit-stop продаёт «вес»?
Можно ли A/B-тестить feel?
Обучается ли feel машинно?
Почему инженеры это недооценивают?
- Steve Swink, «Game Feel: A Game Designer's Guide to Virtual Sensation» (2008) — первоисточник термина.
- «Juice it or lose it» (Martin Jonasson & Petri Purho) — каноничный доклад про juice на простом примере.
- Разборы прыжка Celeste / Mario — coyote time, jump buffering, variable jump height по кадрам.
- Lab 09 —
labs/lab-09-game-feel/, потрогать разницу тумблером.