Почти полный список моих личных проектов
Несколько прототипов игр, эксперименты с процедурной музыкой, разработка модов, два геймджема, пара веб-сайтов и диплом на тему искусственного интеллекта в видеоиграх. Всё с открытым исходным кодом.
До 2015
До 2015 года у меня ничего особо не сохранилось, к сожалению. Тогда я был занят учёбой, занимался программированием микроконтроллеров и ПЛИС, а в свободное время хотел сделать робота. Закупился деталями, купил гусеничное шасси с двумя двигателями, пару сервоприводов, микроконтроллеры AVR ATmega и пару радио-модулей. Для начала просто хотел сделать гусеничную платформу с управлением по радиоканалу, но так ничего и не доделал, так как сложно было совмещать работу, учёбу и проекты.
2015-2016: VT
В какой-то момент я решил, что надо бы сделать свою игру. Я изучал Java, а самой популярной библиотекой для разработки игр на джаве была libGDX. К сожалению, libGDX — это не движок, поэтому кучу вещей пришлось писать самому: переключение сцен, модель актёров, поиск пути и много другого.
Идея игры у меня появилась после того, как я поиграл в Frozen Synapse. Захотелось сделать тактический top-down шутер для мобильных устройств, в котором можно пальцем рисовать траекторию движения персонажа.
Дальше этой идеи дело не ушло, так как появились проблемы с геймдизайном, да и значительная часть времени уходила на разработку базовых вещей в libGDX, а не самой игры.
Технологии: Java, libGDX.
Исходники: GitHub.
2016: Dijkstra vs. A*
К счастью, наработки VT не пропали совсем уж даром. Я доработал прототип и использовал его как полигон для изучения и тестирования алгоритмов поиска пути. Написал курсовую работу по алгоритмам, в которой сравнил производительность алгоритма Дейкстры и A*. Я использовал ассеты игры, чтобы нарисовать, какие шаги проходят оба алгоритма, прежде чем находят оптимальный путь. Получилось познавательно.
Технологии: Java, libGDX.
Исходники: курсовая работа, ветка VT с поиском пути.
2016: Avalon Schedule
В этот раз не игра, а мобильное приложение. В университете на вечернем была проблема: расписание можно было смотреть на сайте, но если были какие-то изм��нения, то никто о них, естественно, не предупреждал. Поэтому я решил сделать приложение на андроид с расписанием занятий.
Оно довольно примитивно загружало страницу с расписанием, парсило HTML, доставало оттуда таблицу с занятиями и показывало на экране. В фоновом режиме оно раз в 1-2 часа загружало это же расписание, сравнивало с сохранённым и, если были отличия, показывало уведомление.
Исходную проблему оно решило, часть одногруппников им успешно пользовалась. Я даже пробовал его продвигать. Распечатал объявление со ссылкой на Google Market и повесил его в холле университета рядом с другими объявлениями. На следующий день его там уже не было. Раз университет не захотел сотрудничать, я забил.
Технологии: Java, RxJava, Android SDK, HTML.
Исходники: GitHub.
2017: Vector Tactics
Продолжая изучать разработку игр, я выбрал соответствующую тему для диплома: «Исследование методов моделирования принятия решений на примере ботов в компьютерной игре». Это название с кучей канцелярита означает, что я просто делал ботов для игры, и сравнивал, какой их них лучше.
Для этого я собрал простой top-down шутер на Unity с одной ареной и небольшим набором правил. На арене есть стены (блокируют обзор и выстрелы), укрытия (блокируют 50% выстрелов), пара аптечек и пара ботов, которые сражаются друг с другом. Назвал его Vector Tactics. Вообще, это название принадлежит VT (который и есть Vector Tactics, просто сокращённо), но так как я его уже вряд ли бы продолжал, название освободилось.
Всего было 4 бота, по одному на каждый алгоритм принятия решений: конечный автомат, дерево поведения, нечёткая логика и нейронная сеть (простой трёхслойный перцептрон). Я их стравливал друг с другом в тысячах боёв и собирал статистику.
Технологии: C#, Unity.
Исходники: GitHub.
2017: Dystopian Horror
В 2016-2017 годах я учился в Wargaming Academy. Подробнее об этом можно почитать у меня в посте о том, как я попал в разработку игр. В качестве проекта я делал хоррор про антиутопию на Unity (жанр и сеттинг выбирались по жребию). На новогодних праздниках в январе 2017 я прошёл примерно десяток хорроров, изучая жанр. Больше всего меня впечатлил Layers of Fear, поэтому я решил сделать игру, в которой окружение меняется, когда игрок не видит.
Игра проходится минут за 5. Игрок ходит по школе в антиутопическом сеттинге во время комендантского часа. Можно заходить в разные комнаты, но когда ты в неё заходишь, она перемещается, и выйдешь ты уже в другом месте.
В комнатах нужно искать книжки (типичная механика для хорроров тех времён). При посещении каждой комнаты у игрока росла шкала безумия. За каждую найденную книжку она уменьшалась. Чем больше уровень безумия, тем более странные комнаты появляются в игре и тем сильнее искажается окружение. В игре даже есть две концовки: для низкого безумия и для высокого.
Я очень доволен архитектурой игры и вообще всем, что связано с кодом. Каждая комната — это отдельная сцена в Unity. У неё есть параметры, при каком уровне безумия она может появляться. Когда игрок подходит к двери, за которой может оказаться одна из этих комнат, игра выбирает все комнаты для текущего уровня безумия и берёт одну из них случайным образом. Когда игрок заходит в комнату, игра делает то же самое, но уже для дверей: игра ищет подходящие дверные проёмы, к которым можно переместить комнату и выбирает один из них. Т.е. игрок может выйти совсем в другом коридоре с совсем другим окружением.
А вот всё, что касается работы с графикой и ресурсами, было сделано, по моему мнению, плохо. Я просто купил пак ассетов для хоррор-школы. Я не разбирался в текстурах и материалах (да и сейчас стало не сильно лучше), поэтому каждая стена была вытянутым кубом, на которую я натягивал текстуру школьной стены. При этом если стены были разного размера, у них были разные материалы, потому что я не знал, как сделать материал, который одинаково хорошо смотрелся бы на стенах длиной и 2 метра, и 10 метров.
Но всех этих проблем с ассетами не видно в готовой игре, а на производительность они не сильно влияли — игра слишком простая для этого. В итоге я получил диплом за лучший проект Wargaming Academy 2017.
Технологии: C#, Unity.
Исходники: GitHub.
2018: Disaster City (RTS-прототип)
В 2018 году я стал подумывать о разработке полноценной игры в свободное время. Мне захотелось сделать игру, в которой ты защищаешь свой город от огромных годзилла-образных монстров. В такой концепт можно засунуть просто огромное количество отсылок: кайдзю (Годзилла, Тихоокеанский рубеж), огромные летающие тарелки (День независимости), ангелы (Евангелион), стена вокруг города (Тихоокеанский рубеж, Атака Титанов), огромные человекоподобные роботы (меха-аниме), тупые военные, открывающие огонь, когда не надо (куча всего).
Я думал, что можно сделать RTS в таком сеттинге. Начал делать прототип, чтобы проверить, будет ли это работать. Взял бесплатные ассеты с городом, каким-то драконом, танками и начал собирать из этого игру.
В первой версии дракон просто крушил город, а игрок мог создавать танки в неограниченном количестве, просто кликая в любом месте. В этой версии я проверял, удобно и интересно ли вообще заниматься микро-менеджментом в таком виде: выбирать юниты мышкой, выбирать, куда им двигаться и куда стрелять.
Потом я стал добавлять экономику. В RTS мы всегда добываем какие-то ресурсы. Какие вообще могут быть ресурсы в таком сеттинге? Я так и не придумал. Решил, что главный ресурс, который может быть в такой игре — это время. У тебя чрезвычайная ситуация, ты можешь вызывать войска в любом количестве, не думая о деньгах, но всегда нужно время, чтобы войска прибыли до места действия.
Я сделал систему с таймерами. Ты можешь вызвать танки, но нужно некоторое время, чтобы они прибыли. Потом еще нужно время, чтобы появились новые танки, прежде чем можно будет их снова вызвать. Стала вырисовываться прогрессия: сначала нужно прокачать какую-то ветку, чтобы можно было вызвать танки. Потом можно делать апгрейды, которые уменьшают время призыва танков, увеличивают количество прибывающих танков, увеличивают им урон и так далее. Я добавил дерево технологий с тремя ветками: танки, авиация и артиллерия.
К сожалению, прототип показал, что играть в это не так весело. Микро-менеджмент в духе классических RTS просто не подходил этом сеттингу. Я вдохновлялся фильмами типа Годзиллы, а RTS, где ты только и делаешь, что гоняешь танки по улицам — это не совсем тот опыт. Хочется чего-то с глобальными решениями.
Сейчас этот прототип уже отменён. У меня есть идеи, в каком жанре развивать идею для этого сеттинга, но пока мне не хватает смелости, чтобы начать полноценно работать над игрой. Возможно, вы ещё когда-нибудь услышите о Disaster City.
Технологии: C#, Unity.
Исходники: GitHub.
2019: Generative Music
В 2019 году я проходил курс по теории музыки на Udemy. Просто захотелось понимать музыку и как она устроена. Тогда же у меня появилась идея заняться генеративной (процедурной) музыкой, т.е. музыкой, которая создаётся с помощью алгоритмов. Есть хорошая презентация на эту тему с интерактивными примерами.
Главная идея была такая: если мы играем в определённом ключе, то все (почти) аккорды в этом ключе будут звучать хорошо. Возможно, вы слышали про такие термины как «ля минор» или «до мажор». Вот это и есть ключ. Не буду углубляться в музыкальную теорию, так как всё равно не смогу ничего объяснить и перевру половину.
У меня в голове это уже выглядело как библиотека для создания процедурной музыки, реагирующей на события. Например, если у тебя что-то обычное в игре, то играет сгенерированная музыка в мажорном ключе. Если начинается драма, то можно переключить ключ на минорный, и музыка сама перестроит аккорды и звучание станет более грустным.
К сожалению, не всё так просто. Оно, может, и звучит неплохо поначалу, но если работать над проектом достаточно долго, то становится понятно, что всё это звучит довольно однообразно. Нельзя просто взять и научить компьютер писать музыку.
Тут есть два варианта.
Первый: использовать машинное обучение и научить компьютер генерировать музыку на основе существующей библиотеки аудио. Это задача для Google, Apple, Spotify или еще кого-нибудь, у кого есть огромная коллекция музыки для обучения алгоритмов. К сожалению, компьютер не будет понимать, что он делает — нейронки просто копируют что-то существующее с изменениями.
Второй: переложить идеи музыкальной теории на код, чтобы компьютер их применял и писал музыку осмысленно. Т.е. чтобы он производил какие-то звуки не просто потому, что какие-то весовые коэффициенты нейронки так сказали, а потому что это аккорд с таким-то названием и он хорошо звучит в таком-то ключе после какого-то другого аккорда.
Мне нравится второй подход, но это очень сложно. У меня нет музыкального образования, и я никогда не писал музыку, поэтому мне очень сложно проектировать подобную систему. Сейчас проект заморожен и мне очень обидно из-за этого. Я бы хотел ещё над ним поработать, но понимаю, что просто не потяну его.
Технологии: C#, Unity.
Исходники: GitHub.
2019-2020: Моды для Beat Saber
В 2019 я решил сделать собственный мод для Beat Saber и разобраться, как они работают в играх на Unity. В Beat Saber нет встроенной поддержки модов, поэтому нужно было их сначала туда как-то добавить. Так я узнал про BSIPA, Unity Doorstop, Mono.Cecil и Harmony. В них используется несколько очень крутых технических решений: например, модификация библиотек игры и движка, внедрение в таблицу импорта DLL и вмешательство в загрузку Mono Runtime, который используется в Unity, чтобы можно было запускать C#-скрипты в движке, написанном на C++.
С этого проекта начался мой блогерский путь на DTF. Я написал две статьи: одна про внедрение модов и одна про разработку:
Ну и свой мод я тоже написал, правда спустя полгода после начала работы над этой темой. Он довольно простой: показывает время, проведённое в игре в текущей сессии (полное и активное).
К сожалению, он больше не работает, так как очень сложно поддерживать моды. Код самой игры постоянно меняется. Код инструментов для модов постоянно меняется. Нужно либо обновлять мод регулярно, либо забить.
Технологии: C#, Unity, декомпилятор C#, C, BSIPA, Unity Doorstop, Mono.Cecil, Harmony.
Исходники мода: GitHub.
2020: Slower Than Light
В январе 2020 я участвовал в Finnish Game Jam 2020 (финское отделение Global Game Jam). Тема джема была «Ремонт». Мы решили сделать игру, в которой инопланетянин на своём космическом корабле пытается добраться до дома. К сожалению, его корабль настолько плох, что ломается несколько раз в минуту.
Для ремонта корабля нужно решать паззлы. Раз в некоторое время какое-то из устройств ломается, и из него вываливаются детали — их нужно поставить на место. Иногда для этого нужно вытащить какие-то другие детали, чтобы засунуть что-то под них, и потом собрать это всё обратно.
Мы хотели вызвать у игрока ощущение того, что местные технологии очень сложны и инопланетянин сам до конца не понимает, как это работает. Поэтому в качестве деталей используются мозги в колбах, непонятные сферы с гравитационными аномалиями и медузы с молниями.
В команде было 3 человека. Я отвечал за геймдизайн и код паззлов.
Технологии: C#, Unity.
Исходники: GitHub.
2020: Сайт Binary machinery
Однажды я узнал, что на GitHub есть сервис GitHub Pages. По сути, это бесплатный хостинг для статических сайтов. Я решил, что можно сделать там свой личный сайт с блогом и портфолио. Судя по описанию, в качестве движка сайта можно взять Jekyll, выбрать там какую-нибудь визуальную тему, а GitHub сделает всё остальное.
На практике всё оказалось сложнее, и мне пришлось самому дописывать кучу всего для шаблонов страниц на смеси HTML, YAML и Liquid и частично переписывать стили в CSS. Ну хоть работает.
Технологии: Jekyll, GitHub Pages, HTML, CSS.
Исходники: GitHub.
2020: Анализ DTF по открытым данным
В какой-то момент я узнал, что у DTF есть API и что здесь используются инкрементные идентификаторы для статей и пользователей. Это значит, что можно просто скачать всех пользователей и статьи, запрашивая их по идентификатору, начиная с 1.
Так я и сделал. За несколько дней я выкачал все доступные данные с DTF и построил кучу графиков и таблиц:
Технологии: Python, PostgreSQL.
Исходники: GitHub.
2020: Кукуха в самоизоляции
В октябре 2020 на DTF был джем от народа с темой «Изоляция». Я был банален и сделал игру про самоизоляцию. Главным героем игры является Кукуха, которой нужно сидеть дома и никуда не поехать (серьёзно, всё это делалось ради этого каламбура).
Для этого нужно каждый день выбирать, чем бы таким заняться, чтобы сохранить рассудок. Например, можно завести б��ог, взять подписку на Flexlix, завести кучу домашних животных или купить консоль и поучаствовать в консольных войнах.
Главная фишка игры — это динамический нарратив, который учитывает решения игрока и их комбинации. Например, если у Кукухи есть блог и домашнее животное, то можно написать пост про животное. Если есть подписка на стриминговый сервис, то могут закрыть её любимый сериал.
Я писал в своём блоге на DTF, как устроена эта система и как она выбирает, что будет дальше:
Я решил использовать этот геймджем, как возможность начать изучать Unreal Engine 4. Из-за этого половину времени я делал не игру, а боролся с движком, так как не знал, как делать базовые вещи. Но вроде бы чему-то научился, так что всё было не зря.
Технологии: C++, Unreal Engine 4.
Исходники: GitHub.
2020: Сайт «Тайный Санта»
Каждый год у нас в семье проводится Тайный Санта. Вместо того, чтобы дарить кучу мелких подарков каждому члену семьи, тебе случайным образом назначается кто-то один, и тебе нужно подарить только один подарок, зато более ценный.
В этот раз мы решили сделать свой сайт, чтобы каждый участник мог зарегистрироваться, указать пожелания, а потом, когда организатор запускает событие, получить письмо с именем получателя и списком того, что он или она хочет в подарок.
Это первый раз, когда я делал веб-проект с нуля. Я выбрал Vue.js для фронта и Python (Flask) для бэкенда. Практически с самого начала разработки я обнаружил, что шутки про огромное количество технологий, фреймворков и библиотек в веб-разработке — это не шутки. Хочешь хранить на сервере сессию пользователя? Вот тебе Flask-Login. Хочешь, чтобы состояние пользователя было доступно всем Vue-контроллерам? Вот тебе Vuex. И так далее.
Ещё я написал статью про алгоритм назначения получателей. Там про теорию графов, гамильтоновы циклы и поиск с возвратом:
Технологии (да, я перечислил вообще все): Python, Flask, Flask-CORS, Flask-Login, Passlib, SMTP, JavaScript, Vue.js, Vue Router, Vuex, Axios, HTML, AWS EC2, nginx, DNS Records, Certbot (Let’s Encrypt).
2021: ?
Сейчас я пока ни над чем не работаю, но у меня в планах один проект на Unreal Engine 4. Ничего серьёзного, просто проект для изучения движка, но я планирую периодически выпускать дневники разработки у себя в блоге.