Что делает игру весёлой: кор-луп

Почему в одни игры залипаешь на час, а другие закрываешь через минуту? Чаще всего дело не в графике, а в кор-лупе — крошечной петле «цель — действие — награда», которая крутится снова и снова.

Кор-луп (core loop) — это главная повторяющаяся петля действий игрока, ради которой в игру интересно играть снова и снова. Если эта петля затягивает — игра живёт. Если нет — никакая красивая картинка не спасёт.

В прошлом уроке мы доделали Змейку: научили её показывать экран проигрыша и перезапускаться по кнопке. И вот что забавно: ты, скорее всего, после рестарта нажал «играть снова» не один раз, а раз десять подряд. Хотя игра — это буквально квадратик, который ест точки. Почему так цепляет? Сегодня разберём это по косточкам, потому что без этого понимания любая твоя следующая игра рискует получиться красивой, но скучной.

Зачем это вообще нужно

Представь, что ты потратил неделю на игру про цыплёнка: нарисовал классный фон, добавил музыку, частицы, плавную анимацию. Даёшь поиграть другу — он тыкает минуту и кладёт телефон. «Ну, прикольно». И всё. Обидно до жути.

А теперь вспомни мобильную игру, в которой графики на три копейки — какой-нибудь бесконечный раннер или 2048. Ты в неё рубишься в автобусе, в очереди, перед сном «ещё один разочек». В чём разница? В первой игре нет работающего кор-лупа, а во второй он отлажен до блеска.

Кор-луп — это сердце веселья. Не графика, не сюжет, а вот эта маленькая петля, которую игрок повторяет сотни раз за сессию. К концу урока ты научишься видеть её в любой игре и описывать кор-луп своей будущей игры одним абзацем — ещё до того, как напишешь хоть строчку кода. Это сэкономит тебе те самые потраченные впустую недели.

И ещё одна важная мысль наперёд. Кор-луп — это не игровой цикл (game loop), хотя названия похожи и их легко спутать. Игровой цикл — это техническая штука: «обработать ввод — обновить состояние — нарисовать кадр», которая крутится 60 раз в секунду, и о ней мы говорили в самом начале курса. Кор-луп же — про чувства игрока, про то, что он осознанно делает руками снова и снова: бежит, ловит, собирает, прокачивается. Один — про железо и кадры, другой — про азарт. Держи это различие в голове, оно пригодится в квизе.

Метафора: игра как припев любимой песни

Знаешь, почему хит застревает в голове? Из-за припева. Куплеты можно и забыть, но припев цепкий, короткий и повторяется снова и снова — и ты ловишь себя на том, что напеваешь его в душе. Кор-луп игры — это её припев.

Куплеты — это всякая обёртка: меню, сюжетные вставки, выбор персонажа, экран магазина. Их в игре немного, и проходишь ты их по разу. А припев — это то, что ты делаешь постоянно: бежишь, прыгаешь, стреляешь, собираешь. Если припев скучный, песню выключают, сколько бы умных куплетов в ней ни было.

И тут есть честное правило, которое легко проверить на себе. Сколько раз за пять минут игры ты прокручиваешь кор-луп? В хорошей игре — десятки, а то и сотни. Сколько раз ты заходишь в меню или смотришь катсцену? Пару раз, и то не всегда. Получается, что 95% времени игрок проводит именно в кор-лупе — значит, и вылизывать в первую очередь надо его, а не красивую заставку, которую увидят один раз. Дизайнеры так и говорят: «время игрока тратится там, где петля», — и направляют туда всё своё внимание.

Хороший кор-луп держится на трёх китах: цель → действие → награда. У игрока есть понятная цель, для неё есть приятное действие, и за выполнение он сразу получает награду, которая тут же ставит новую цель.

Разберём эту тройку по частям, потому что сломаться может любое звено:

ЗвеноЧто этоЕсли сломано
Цельчего игрок хочет прямо сейчаснепонятно, что делать — скука
Действиечто игрок для этого делает рукаминеприятное управление — раздражение
Наградачто он получает за успехнет отклика — «зачем я это делал?»

И ключевое: награда должна тут же подкидывать новую цель. Тогда петля замыкается сама на себя и крутится без остановки. Именно это «и снова цель» превращает три отдельных шага в бесконечный цикл.

Разбор 1. Кор-луп Змейки

Возьмём игру, которую мы только что доделали. Кажется, что там и разбирать нечего — но кор-луп там идеальный, поэтому она и затягивает.

  • Цель: съесть яблоко. Оно всегда на экране, всегда видно, всегда понятно, куда ползти.
  • Действие: вести змейку стрелками так, чтобы дотянуться до яблока и не врезаться в себя.
  • Награда: змейка стала на сегмент длиннее, счёт вырос на единицу.

А теперь магия: награда (длиннее змейка) сама создаёт новую цель — появляется новое яблоко, но теперь дотянуться до него сложнее, потому что хвост стал длиннее и места для манёвра меньше. Петля замкнулась и тут же стала чуть напряжённее. Ты съел яблоко — и сразу хочешь съесть следующее, потому что счёт прямо на глазах растёт, а риск приятно щекочет нервы.

Если описать это в коде, то весь кор-луп Змейки прячется в обработчике поедания яблока — буквально в нескольких строчках:

// это вызывается, когда голова змейки попала на клетку с яблоком
function onAppleEaten() {
  score += 1;          // НАГРАДА: счёт вырос
  snake.grow();        // НАГРАДА: змейка стала длиннее
  spawnApple();        // НОВАЯ ЦЕЛЬ: яблоко появилось в другом месте
  // действие игрока (управление стрелками) идёт в игровом цикле каждый кадр
}

Результат: игрок видит, как счёт мгновенно подскочил, змейка дёрнулась и удлинилась, а на поле вспыхнуло новое яблоко в другом углу. Глаз сразу цепляется за новую цель, рука уже ведёт змейку туда — петля провернулась за доли секунды, и игрок даже не успел заметить, что «начал заново».

Обрати внимание: три из четырёх строк — это про награду и новую цель. Действие (управление) живёт отдельно, в игровом цикле, и крутится каждый кадр. Вот так выглядит кор-луп изнутри — он почти всегда оказывается совсем маленьким куском кода, но именно он держит всю игру.

Разбор 2. Кор-луп платформера про цыплёнка

Теперь возьмём то, к чему мы идём весь курс, — платформер, где цыплёнок прыгает по уровню, собирает монетки и убегает от врагов. Тут петля чуть жирнее, но устроена так же.

  • Цель: добраться до конца уровня, попутно собрав как можно больше монеток.
  • Действие: бегать и прыгать — рассчитывать прыжки через ямы, перепрыгивать врагов, дотягиваться до монеток над платформами.
  • Награда: монетка собрана (звон + счёт), участок уровня пройден, открылся следующий кусок.

И снова награда рождает цель: собрал монетку — глаз уже ищет следующую, чуть подальше и чуть труднее. Прошёл сложный прыжок — впереди виден ещё более коварный. Петля «вижу монетку → прыгаю → звон и +10 → вижу следующую» крутится десятки раз за минуту.

В коде ядро этой петли — обработчик сбора монетки, и он подозрительно похож на змеиный:

// вызывается, когда AABB цыплёнка пересёкся с монеткой
function onCoinCollected(coin) {
  chicken.coins += 1;        // НАГРАДА: счётчик монет вырос
  playSound('coin');         // НАГРАДА: приятный звон — отклик игроку
  spawnParticles(coin.x, coin.y);  // НАГРАДА: искорки на месте монетки
  coin.dead = true;          // монетка исчезает
  // НОВАЯ ЦЕЛЬ: следующая монетка уже лежит дальше по уровню
}

Результат: цыплёнок коснулся монетки — раздаётся звонкий «дзынь», на её месте брызжут золотые искорки, счётчик монет в углу прибавляет единицу, а сама монетка пропадает. Игрок мгновенно чувствует, что сделал что-то хорошее, и уже несёт цыплёнка к следующей блестяшке впереди.

Сравни два обработчика — onAppleEaten и onCoinCollected. Структура одна: дать награду (счёт, звук, частицы), убрать старую цель, подсунуть новую. Разные игры — один скелет кор-лупа. Когда ты это видишь, придумывать новые игры становится в разы легче.

Разбор 3. Зачем награде сразу давать новую цель

Самая частая ошибка новичка — сделать цель и действие, но забыть про последнее звено: чтобы награда тут же зажигала следующую цель. Давай сравним два варианта одного и того же платформера.

// ВАРИАНТ А: петля замыкается — награда даёт новую цель
function onCoinCollected(coin) {
  chicken.coins += 1;
  playSound('coin');
  coin.dead = true;
  // на уровне разбросаны ещё монетки — глазу есть за что зацепиться
}

// ВАРИАНТ Б: петля рвётся — собрал единственную монетку и всё
function onCoinCollected(coin) {
  chicken.coins += 1;
  coin.dead = true;
  // больше монеток нет, новой цели не появилось — игрок завис
}

Результат: в варианте А игрок, собрав монетку, сразу видит следующую и бежит дальше — петля крутится, играть хочется. В варианте Б после единственной монетки экран «пустеет»: цели нет, награды больше не предвидится, и игрок выходит из игры со скучающим лицом. Код почти одинаковый, а ощущение от игры — противоположное.

Вывод простой: награда без новой цели — это тупик. Игроку должно быть понятно, что делать в следующую секунду, иначе петля рвётся. Поэтому, проектируя игру, всегда спрашивай себя: «Он получил награду — а дальше-то что? Куда побежит его взгляд?»

А ещё петлю солит риск

Есть и приправа, без которой даже замкнутая петля быстро приедается, — это риск. Сравни: в Змейке ты не просто ползёшь к яблоку, ты ползёшь к нему, рискуя врезаться в собственный хвост. В платформере ты не просто дотягиваешься до монетки, ты тянешься к ней над ямой, в которую можно сорваться. Награда тем слаще, чем выше была ставка.

Если убрать риск совсем — петля станет пресной. Представь Змейку, в которой нельзя проиграть: ешь себе яблоки бесконечно. Через минуту скучно, потому что нет напряжения, нет того щекочущего «ой, чуть не врезался». А вот когда каждое яблоко даётся с лёгким холодком — петля держит. Поэтому, описывая кор-луп, держи в голове и четвёртый необязательный, но мощный ингредиент: чем игрок рискует, тянясь к награде. Это превращает рабочую петлю в по-настоящему азартную.

Частые ошибки и подводные камни

1. Сначала графика, потом кор-луп

Самая дорогая ошибка. Ты неделю рисуешь спрайты и фон, а потом оказывается, что играть-то скучно. Делай наоборот: сначала собери уродливый прототип из квадратиков, где кор-луп уже работает и затягивает, и только потом наряжай его. Если квадратики не цепляют — не зацепят и красивые спрайты.

2. Непонятная цель

Игрок запустил игру и не понимает, чего от него хотят. Куда идти? Что собирать? Если первые пять секунд он стоит в растерянности — петля даже не запустилась. Цель должна быть видна сразу: яблоко на экране, монетка впереди, дверь со светящимся выходом.

3. Награда без отклика

Игрок что-то сделал, а игра промолчала: ни звука, ни вспышки, ни прироста счёта. Мозг такое не засчитывает как награду. Даже +1 к счёту должен сопровождаться хоть каким-то откликом — звоном, частицами, дрожанием числа. Без отклика действие ощущается бессмысленным.

4. Действие неприятно делать

Цель ясна, награда есть, но управление кривое: цыплёнок прыгает с задержкой, поворачивается рывками, проваливается сквозь платформы. Если само действие раздражает, никакая награда не спасёт — петля крутится через силу. Доводить управление до «приятно жать» — отдельная важная работа.

5. Петля слишком длинная

Если между действием и наградой проходит минута (долгая загрузка, длинная катсцена, медленная анимация), петля провисает. Чем короче цикл «действие → награда → новая цель», тем сильнее затягивает. В Змейке он длится доли секунды — поэтому она и гипнотизирует.

Мини-практика: опиши кор-луп своей игры

Теперь твоя очередь — и тут не нужно ни строчки кода, только голова и пара минут. Придумай любую простую игру про нашего цыплёнка (можно взять идею из головы — например, «цыплёнок ловит падающие зёрнышки в корзинку») и опиши её кор-луп.

  1. Сформулируй цель одним предложением: чего игрок хочет прямо сейчас? (Например: «поймать падающее зёрнышко».)
  2. Опиши действие: что игрок делает руками? Какими клавишами? (Например: «двигать корзинку стрелками влево-вправо».)
  3. Опиши награду: что он получает за успех и как игра ему об этом сообщает? (Звук, счёт, частицы?)
  4. Самое важное — проверь, что награда создаёт новую цель. После пойманного зёрнышка сразу падает следующее? Если нет — придумай, как замкнуть петлю.
  5. Запиши всё это в один абзац по шаблону: «Игрок хочет ..., для этого он ..., за успех получает ..., и сразу появляется новая цель — ...».

Проверь себя по чек-листу: видна ли цель в первые секунды? Приятно ли делать действие? Есть ли у награды отклик? Подкидывает ли награда новую цель? Если на все четыре вопроса «да» — у тебя на руках работающий кор-луп, и такую игру уже не стыдно собирать в коде.

Вот пример хорошего ответа, чтобы свериться:

«Игрок хочет поймать падающее зёрнышко, для этого он двигает корзинку под цыплёнком стрелками влево-вправо, за успех получает звонкое дзынь и +1 к счёту с золотой вспышкой, и сразу сверху падает новое зёрнышко — чуть быстрее предыдущего, чтобы было напряжённее».

Итоги

Сегодня ты понял, что делает игру по-настоящему весёлой, — и это не графика:

  • Кор-луп — это главная петля действий, которую игрок повторяет снова и снова; в ней всё веселье.
  • Держится петля на тройке цель → действие → награда, и слабое звено ломает всю игру.
  • Главный секрет — награда сразу даёт новую цель, и петля замыкается сама на себя.
  • И в Змейке, и в платформере ядро кор-лупа — это крошечный обработчик («съел яблоко», «собрал монетку»), а вокруг него крутится вся игра.
  • Кор-луп проектируют до кода и графики — сначала рабочая петля из квадратиков, потом красота.

Теперь ты умеешь видеть скелет любой игры и описывать кор-луп своей будущей одним абзацем. Это суперсила геймдизайнера: ты можешь оценить, будет ли игра весёлой, ещё до первой строчки кода.

В следующем уроке мы займёмся вторым китом веселья — сложностью и балансом: разберём, почему игра должна становиться труднее ровно с той скоростью, с какой игрок становится круче, и как не сделать её ни слишком лёгкой, ни слишком злой.

Проверьте себя
1. Что такое кор-луп (core loop) игры?
AГлавная повторяющаяся петля действий, ради которой в игру интересно играть снова
BБесконечный цикл requestAnimationFrame, который перерисовывает кадры
CМеню игры, через которое игрок заходит в уровень
DНабор спрайтов главного героя
2. Из каких трёх звеньев состоит хороший кор-луп?
AМеню → игра → пауза
BЦель → действие → награда
CЗагрузка → уровень → титры
DВвод → обновление → отрисовка
3. Почему важно, чтобы награда сразу создавала новую цель?
AЧтобы игра работала на 60 FPS
BЧтобы петля замкнулась сама на себя и игрок не завис без понятной следующей цели
CЧтобы сэкономить память браузера
DЧтобы спрайты грузились быстрее
4. Что является наградой в кор-лупе Змейки?
AПоявление меню после смерти
BРост счёта и удлинение змейки на сегмент
CСмена цвета фона
DУскорение движения стрелок
5. Какой подход к разработке игры правильный согласно уроку?
AСначала нарисовать всю графику и музыку, потом думать про геймплей
BСначала собрать прототип из квадратиков с рабочим кор-лупом, потом наряжать его
CСразу писать финальную версию игры целиком
DНачать с экрана проигрыша и рестарта
6. Почему в платформере про цыплёнка обработчик сбора монетки проигрывает звук и показывает частицы?
AЧтобы нагрузить процессор и снизить FPS
BЧтобы дать награде отклик — без него мозг не засчитывает действие как награду
CЧтобы заменить дельта-время
DЧтобы удалить монетку из памяти быстрее