Выпустил первую игру!

Костя kik0s Амеличев · June 14, 2026

Прежде чем почитать – поиграйте в саму игру!!!!

Мой игровой бекграунд

Я очень долго думал, что хочу делать игры. Когда я только учился программированию, я думал, что это верх программистской карьеры. Это же очень круто – когда у тебя какой-то арт есть, кнопочки, интерактивность, все двигается.

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

Первый проект, похожий на игру, я написал где-то в районе 11го класса. Я хотел генерализовать игру Dual, в которую я играл со своим лучшим другом Петей. Я написал клиент-сервер на сокетах, используя python и pygame. Петя нарисовал несколько текстурок, и получился очень угарный вариант игры для компов. По моей задумке, в него можно было бы играть, создавая комнату в локальной сети.

Оказалось, что запустить игру на чужом компьютере… Сложно. Я нашел какой-то упаковщик, который должен был генерировать запускаемый файл с игрой – но они работали через жопу. Кажется, я справился сделать так, чтобы игра запускалась на винде и линуксе (потому что мог их протестировать на компьютерах дома). У Пети был макбук, у него ничего не заработало, и я забросил проект.

С приходом нейросетей, кстати, я переписал все на тайпскрипт одним днем, и теперь в соло-режим можно играть в вебе. Локально поднять сервер, возможно, тоже можно, но я не тестировал. Энивей, ссылка тут.

Графика

Оказавшись в универе, я как-то для себя понял, что концепция программирования игр мне нравится, но как будто бы индустрия сумасшедшая. Там и увольняют всех, и переработки гигантские, и платят в среднем плохо. Тем не менее, там есть серьезные технические интересные задачи. Всякая 3д-математика – очень круто же!

Я так решил на 2 курсе сделать свой небольшой 3д движок, чтобы совместить мое новое знание линейной алгебры с чем-то, что действительно напоминало бы 3д игру. В общем, я сделал что-то очень странное – написал 3д-движок целиком на CPU, который рисовал экран попиксельно, не пользуясь шейдерами вообще. Они были под капотом какой-то небольшой либы, которую я юзал, но сам я пользовался только примитивом setColor(x,y,color).

Мне очень понравилось копаться в таких приколах, захотелось что-то еще попробовать. Оказалось, что на ФКНе особо не было курсов в “визуальном” направлении. Я попробовал взять какой-то курс из гарвардского набора CS50, который был бы введением в геймдев. Это было интересно, я сделал сколько-то проектов, но мне не понравилось, что там везде было предоставлено очень много кода по умолчанию, за счет чего я достаточно плохо понимал, что происходит на самом деле. Типа, в фреймворке несложно заставить картинки двигаться, а как сам фреймворк-то работает?

Какие-то курсы по компьютерному зрению и всяким смежным темам я смотрел, что-то про OpenGL читал. Системного знания у меня совсем-совсем не было, но я хотел разобраться в том, как все эти визуальные системы работают. И пошел в магистратуру на AI & Advanced Visual Computing. По идее, оптимальная траектория, чтобы разобраться в том, что там под капотом. Не буду тут лишний раз ругаться на эколь политехник, но оно того не стоило, в общем, так я экспертом и не стал.

Веб

Паралелльно со всеми этими приключениями в графике, я работал software engineer’ом, потому что прокармливать себя-то надо было. В основном бекендом занимался, но в целом что только не успел поделать. В частности, я успел поделать софт в браузере – и понял, что браузерное апи гораздо лучше позволяет делиться софтом, чем собирание бинарников, которые надо как-то передавать на другую операционную систему. Из минусов – хз, я как-то подумал, и минусов для своего случая не нашел. Ну вернее был один, что код в вебе на джаваскрипте пишется – но оказывается, его уже давно решает wasm, webgl и emscripten. Пиши себе на плюсах, а оно там дальше как-то само соберется.

И я как-то подумал – ну ведь наверняка можно сделать такой фреймворк для себя, чтобы он и в локальный билд собирался, и в веб? Тогда я смогу делиться своей игрушкой без каких-либо проблем, и разрабатывать буду нормально, на каком-то своем фреймворке, с пониманием результатов и своим тулингом. Да, AAA игры на этом не напишешь, но я к этому моменту понял, что это не career choice, а hobby choice.

Короче, я потыкался, собрал прототип на OpenGL / WebGL, вроде заработало. Придумал собрать свою ECS, которая получилась вполне разумной и приятной. У меня есть идея игры, которую я хотел бы сделать, но она оказалось достаточно масштабной, и я после первых прототипов понял, что не потяну этим заниматься.

Грибы

Люся в какой-то момент собрала себе в инстаграм-портфолио смешной арт-прототип игрушки с грибами, где надо ловить грибы. Ну и я подумал – вообще-то, это очень простой код, наверняка я должен суметь такое сделать.

Решил, что это должна быть нормальная игра. Типа, я хочу пройти все стадии создания – протестировать нормально, поэкспериментировать, придумать какую-то интересную фишку, все по списку.

В общем, пошел прототипировать.

Геймплей

Я долго думал, вокруг чего сделать прототип. Понятно, что основной процесс в игре должен быть простой – грибы падают, надо двигаться героем и ловить. Несколько прямоугольников, поверх которых рисуются картинки. Счетчик еще. Если гриб падает – все, game over.

Все хорошо, но очень прямолинейно. Просто лови все, что видишь.

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

Прототип такой игрушки собирается за полдня, когда ECS, утилити для рендеринга и сборка в веб уже написаны. А, и еще утилити для отрисовски текста – freetype это такой страшный страх, что проще картинками цифры вставлять было первое время.

На этом можно в целом заканчивать, публиковаться и писать очередной туториал на хабр. Но я хотел нормальную игру. Может, маленькую и простую, но нормальную.

Бесконечно улучшаемся

Быстро стало понятно, что если какие-то грибы ловить не надо, чтобы не портить рецепт, то и ронять их тоже нехорошо. Было решено добавить стрельбу – чтобы ты подстреливал те грибы, которые собирать не собираешься. А падение на землю, соответственно, забирает жизни.

Это оказалось лучше, но в это тоже невозможно было играть. Спавн грибов происходил моим рандомайзером, и он радостно мог заспавнить одновременно грибы в разных частях экрана – и ведь не поймаешь их никак! Можно, конечно, перепройти уровень, со знанием рандома, и подстрелить один из двух.. Но все хаки какие-то.

Проблема простая – ломать грибы можно издалека и наперед с помощью выстрелов. А ловить можно только то, что ровно сейчас на твоем уровне. Хочется, чтобы можно было заранее поймать какой-то гриб. Так и родился механизм ловушек.

В целом, на этом игра была закончена геймплейно. Это очень простая игра. Мы пошли пробовать и тестировали, тестировали и тестировали до посинения.

Навскидку, надо было добавить следующее:

  • Чтобы можно было играть с телефона, у меня был уже готовый самописный джойстик и кнопки. Выяснилось, что ими невозможно играть, потому что слишком мелко – пришлось вынести на уровень веба, поставив большие кнопки с эмодзи.
  • Раз есть кнопки и есть веб, то надо бы сделать так, чтобы везде было написано, какая кнопка чему соответствует – и, в идеале, чтобы можно было еще поменять биндинг кнопок.
  • Чтобы был биндинг кнопок, нужно меню настроек.
  • Чтобы было меню настроек, нужно основное меню и меню паузы.
  • Когда грибы появляются, ломаются, падают, съедаются итд – нужно добавлять какие-нибудь маленькие дерганья и particles, иначе никакого вайба
  • Надо добавить какую-то аудиодорожку, иначе никакого вайба
  • А раз есть аудио, надо добавить слайдер для регулировки громкости
  • Конечно же нужен туториал
  • А если есть туториал, то нужен и кеш браузера, чтобы не показывать его при каждом старте игры
  • Кстати, еще нужно кешировать пройденные уровни и результаты бесконечного уровня
  • Кстати о бесконечном уровне – там надо добавить шарилку результатов, чтобы можно было получить вордл-эффект.
  • А чтобы бесконечный уровень был интересным, и при этом им можно было соревноваться с друзьями, нужно чтобы сид рандома зависел от дня календаря.

И это я опускаю такие вещи, как калибровки численных параметров – движения, стрельбы, скоростей, сложностей уровней.

В какой-то момент мы поняли, что стрелять пулями странно – придумали стрелять летучими мышами. Тогда само собой случилось очень разумное ограничение, что есть всего три доступные летучие мыши – и на ловушки, и на выстрелы. Для них добавились таймеры на перезарядку, они стали возвращаться к игроку.

Тогда же мы выяснили, что 3 жизни – это очень странное ограничение, если уже есть рецепт, в котором ты уже и так балансируешь между ограничениями. Подумав немного, мы поняли, что это просто два разных режима – попроще (без рецепта, с жизнями) и посложнее (с рецептом, без жизней).

Наверное, есть еще с десяток потенциальных решений, но мы решили остановиться на том, что есть сейчас.

Активная разработка

Изначально я очень много времени потратил в движок сам по себе, делая какие-то прикольные штуки в стол. Обычно у меня находился один выходной в две недели, когда я мог основательно засесть часа на четыре написать какого-то кода. Так, наверное, полгода продлилось примерно суммарно с большими перерывами на всякие сайд-квесты.

В какой-то момент, когда у меня уже был готов основной геймплей и было решено, что это будет игра про ловлю грибов, настал момент для полировки – который, как видно по прошлой части, тратит 90% усилий. Моего энтузиазма бы не хватило даже близко, потому что надо переделывать просто все по кругу раз десять. К счастью, в этот момент случился агентский AI, а у меня случился Pro-шный Codex. Я перестал писать код и начал просто промптить, переписал половину кода из черновых репозиториев в нормальное разделение движок-игра, и запилил все маленькие фичи и улучшения из списков выше. Это был шикарный опыт, потому что примерно все необходимые действия абсолютно очевидны, но мануальны – поэтому можно подумать днем, что надо сделать, а потом одним запросом поставить агента работать, пока вечером смотришь фильм с женой.

Короче, вот! Сделал первую нормальную игру, очень доволен. Есть надежды, что когда-нибудь доделаю другие, более прикольные проекты на этом же движке сделаю.