Любовь в ненависть indie gamedev'a

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



Всем привет! Меня зовут Рома и я несколько лет разрабатываю для embedded на, прости господи, С/С++. Программирование для меня чуть больше, чем работа. Отсюда и желание иметь какой-либо собственный проект, который будет расти, а с ним и мой профессионализм. Я в это верю, во всяком случае. Было перепробовано много языков и технологий, было много идей и столько же провалов. Думаю, кто-то узнал себя. В этом посте будет рассказано о старте разработки компьютерной игры на С++ с использованием OpenGl. Далее будет про следующее:


  1. Сложности, возникающие передо мной и подходы к их решению.
  2. Обзор используемых технологий и средств разработки.
  3. Ссылки на использованные ресурсы в сети.

Чего далее не будет:


  1. О тонкостях разработки на C++. Язык будет упомянут с той степенью абстракции, чтобы его можно с легкостью заменить на другой, нативно поддерживающий ООП.
  2. О готовых движках и их использовании. Ничего не имею против, я даже ЗА. Но пост о другом.
  3. О великолепной картинке, использующей шейдеры последнего поколения. До этого пока далеко.

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


Старт и провал


Краткие обзор инструментов для разработки 2D-игры без какого-либо движка показал, что сразу предстоит выбор фреймворка для обработки мыши, клавиатуры, а также поддержки аудио и отображения графических примитивов. Выбрана была библиотека SFML. На знакомство ушло около недели, было кое-что набросано: по прямоугольному полю ездили танки и убивали друг друга, была возможность строить их фабрики и тому подобное в духе RTS начала 2000-х. Это показалось унылым и захотелось 3D. О 3D я знал меньше, чем javascript о безопасности типов. Гугл первым выдал OpenGl, который выходит из моды. А также про рекомендации использовать так называемый Core Profile этого OpenGl. Кто я такой, чтобы писать по устаревшим методикам? Из попыток скрестить Core Profile c SFML выяснилось, что SFML именно этот профиль одновременно с использованием своего графического модуля не поддерживает. Это был сильный удар по морали, так как на изучение SFML были потрачены ресурсы. К тому же не вся кодовая база была абстрагирована от графической библиотеки.


GLFW и новая надежда


Как следует из названия раздела, Core Profile OpenGl и GLFW прекрасно уживаются. Основной ресурс, используемый мной по OpenGl. Да-да, без VPN скорее всего не откроется, спасибо защитникам рунета. Вспомогательный. Через неделю-две по экрану будут плавать простые геометрические элементы с текстурами. Переход на GLFW с SFML научит кого-то угодно ценить Dependency inversion principle (D в SOLID). В результате на свет появилось это



У меня не было иллюзий относительно эстетической стороны вопроса, однако прототип был жив. Да, он был некрасив, но все знают известную сказку. Настроение поправилось. На тот момент была решена самая сложная на сегодня для меня задача: создание модели с анимацией. Задача была разбита на подзадачи:


  1. Создание анимации в редакторе, например, в Blender.
  2. Экспорт в поддерживающий анимацию формат, например, Collada.
  3. Импорт на C++, например, с библиотекой Assimp.
  4. Проектирование классов и их реализация, используя OpenGl.

Таким образом, танки получили вращающуюся башню.


Когда горд работой, но стыдно её показать


Да, сегодня не все могут по-достоинству оценить великолепно спроектированные абстракции, особенно когда их нет. Нужно было что-то, что бы радовало глаз. Этим чем-то стал процедурный ландшафт. Генератором стал давно всем известный, но не мне, шум Перлина. Выяснилось, что есть параметры, требующие эмпирического подбора. Перекомпиляция – это удар по психике, поэтому появилась потребность в GUI для прототипирования. Результатом поиска стала блестящая библиотека ImGui. С ней численные параметры, цвета, режимы отображения настраивать одно удовольствие. Итог работы получившегося генератора


img


Немного тумана


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



Тот момент, когда понадобились алгоритмы


Да, это случилось. Второй раз за 5 лет. Речь о поиске пути между двумя точками при наличии препятствий, ведь не могут же наземные юниты передвигаться по горам! На помощь приходит алгоритм A*. Псевдокод брал отсюда. Реализация требует профилирования и оптимизации, как и много где ещё, однако в текущем варианте юниты объезжают препятствия, если путь вообще существует. Где-то в этот момент оформилась идея игры.


Космос, который мы…


Рабочая идея, которая будет эволюционировать – освоение планеты первопроходцами. Создание био-, атмо-, и в конечном итоге, экосферы. Приведу пример. Первоначально жизнь будет возможна лишь внутри искусственно созданного купола, внутри которого можно будет выращивать живое: растения, животных. Они в свою очередь будут воздействовать на ландшафт. Далее представлен пример купола и ландшафта под ним через N и M итераций, N < M.



О Меркаторе, Земле и политике


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


Если о том, что прямоугольник натянуть на сферу без искажений нельзя, я подозревал, то количество способов отображения стало откровением. Наиболее распространённая проекция Меркатора имеет проблемы с отображением у полюсов и сильно искажает пропорции при удалении от экватора. Да так, что кажется, что РФ больше Африки, а США — Австралии.


Аналитически подсчитана может быть, как оказалось, также и мера искажения. Грубо говоря, окружность на плоскости становится эллипсом на сфере и наоборот. Задача получилась следующая: к плоскому виду добавить вид на шарообразное тело. Отсюда проблема – какой вид выбрать за основной, а какой отображать с искажениями. Решено было отображать без искажений плоский вид как вид допускающий больше операций, включая выделение и перемещение юнитов. Вид на шарообразное тело оставлен для операций с летательными аппаратами, например, искусственными спутниками. В качестве отображения используется Gall stereographic projection как одно из компромиссных. Искажения подсчитывались при помощи эллипсов искажения, они же индикатрисы Тиссо. В результате можно видеть следующее: на скриншоте представлен вид на планету как на шарообразное тело с двумя куполами, один из которых питает два источника энергии, другой – один источник.


img


Программные модули и цикл разработки


Задачей-минимум на этапе “Начинать ли вообще?” было следующее: эволюционировать от простого к сложному и красивому в течении года. Крайне легко за пару недель от любви к проекту дойти до отвращения. У меня на это пять причин:


  1. Первая причина это код. Без поддержки вменяемой архитектуры и рефакторинга, большая часть времени будет багфиксом, а какая в нём радость?
  2. Недостаточная концентрация на одном. Занимаясь час алгоритмом, час — моделью в Blender, мне не добиться цели.
  3. Излишняя концентрация. Занимаясь движком и алгоритмами долгое время, картинка не меняется и кажется, что прогресса нет.
  4. Сложность в освоении инструмента. Богатство интерфейса Blender или API OpenGl внушает уважение, если не страх. От старта до первого proof of concept может пройти несколько дней, что сильно бьет по морали.
  5. Завышенные ожидания и неготовность к провалу. Порой сложно отказаться от подхода “Спроектировать, реализовать и не возвращаться” в пользу “Прототип/Реализация/Уточнение интерфейсов”

Являясь поборником TDD, должен сказать, что не вижу возможности его применять при таком проценте R&D. Буду рад, если Вы, уважаемый читатель, дадите мне повод усомниться.


На данный момент выделились следующие области разработки:


  1. Проектирование моделей в Blender.
  2. Реализация алгоритмов и математики, например, A* или Perlin Noise.
  3. Разработка “движковой” части. Под ней понимается, например, генератор ландшафта или импорт модели из Blender.
  4. Разработка модуля, ответственного за рендеринг.
  5. Разработка логики игры. Требуется, чтобы она использовала движок и модуль рендеринга.
  6. Рефакторинг.

В планах разделение модулей 2-5 на уровне библиотек с выделением фасада в каждой. Одна из возможных причин: добавление функционала по управлению камерой требует каскадной перекомпиляции большого количества исходного кода.


Практика показывает, что продуктивно получается работать, если фокусироваться на одной области в течении 5-10 часов. Меньше — фокус теряется, больше — замыливается глаз.


Периодически для достижения цели вижу возможным нарушать некоторые правила нормальной разработки, при условии, что будет помечено место нарушения и выделено время на рефакторинг. Последний случается раз в 7-10 дней. Пример: временно создаются глобальные переменные. От них избавлюсь, передав в конструкторы/методы при рефакторинге, что поможет выделить классы с низкой связностью и высоким зацеплением. Что повлечет новый виток рефакторинга. Плюсы подобного подхода:


  1. Готовность к реализации новых идей. Отказ от старых.
  2. Возможность эволюции интерфейсов.

Минусы:


  1. Рефакторинг может затянуться.
  2. Мне видится нереальным поддержка unit/mock тестов.
  3. Некоторые, преодолеваемые, сложности в Vim. Зачем Vim, если он добавляет минусы? Затем что плюсов для меня больше.

To be continued


Благодарю за внимание к моему скромному посту! Весь код здесь. Помимо описанных выше задач много времени ушло на знакомство с Blender, кастомизацию vim и рефакторинг в нем. Если было хоть немного интересно, напишите, пожалуйста. Могу более детально осветить что-то в одном из следующих постов. Видео с чуть большим количеством деталей по реализации тут.

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 21

    +1

    Всё так, TDD в геймдеве не приживается обычно. Ровно по той причине, что даже когда примерно понятно, что делаем, все равно какой-то постоянный RnD — механики, идеи, дизайн меняются. Так что не расстраивайтесь.

      0
      Спасибо! Буду иметь в виду.
      –2

      Цель то какая? Игру зачем делаете? Научиться и пойти в геймдев? Продать мильонам школьников через стим? Занять свободное время?

        0
        Задача минимум — повысить навыки проектирования в целом и С++ в частности.
        Задача максимум — заработать. Положительные эмоции, если кому-то окажусь полезным, репутацию и, конечно, деньги.

        Школьники — в негативном контексте? Почему? Я тоже был школьником. А Вы?
          –1
          «продать школьникам» в негативном контексте)) Они неплатежеспособны, наверно))

          Не буду врать, опыт в играх у меня околонулевый, как создании, так в игрании))
          Но мне казалось более важной «играбельность», чем графика. Вы вот в свою игру позалипали хотя бы часик-другой, пусть даже играя квадратиками, стреляющими треугольничками? «Азарт» какой-то у вас был? И уж тем более инди не могут себе позволить упираться в графику… Она на то и инди, что пытается найти какие-то мелкие фенечки, а не сделать графику уровня ААА.
        +1

        Я тоже так примерно начинал, упорно игнорировал unity (конечно появилась огромная база, помогает, но...) А потом оказалось, что код — самое простое по большей части. Берите Юнити и делайте игру… просто писать код вы и так умеете.

          0
          Основной ресурс по OpenGL, упомянутый в статье, полностью переведён здесь, на Хабре.
          habr.com/ru/post/310790 — ссылка на первую статью. Правда содержание там неполное, но по мере продвижения оно будет появляться. Где то к 3 или 4 части в содержании появятся все ссылки.
            0
            Всё так, мне стоило это указать.
            +1
            Настоятельно рекомендовал бы использовать готовый движок. Я знаю случаи, когда «любители собственных движков» тратили огромное количество времени и сил на разработку, а затем, после запуска, игра полностью сливала репутацию из-за большого количество крашей, несовместимостей и другими непредвиденными прелестями, которые никак не проявлялись в течении всего срока тестирования на, казалось бы, довольно большой аудитории.

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

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

              ЗЫ: Вон, вспомнить тех же Battle Brothers, написанных на electron. Мягко говоря не самая типичная обертка для игрушек, а получилось очень даже отлично.
                –1
                Не для всех игр нужен «навороченный» движок

                А никто и не говорит про навороченный движок. Просто актуальный движок.

                ЗЫ: Вон, вспомнить тех же Battle Brothers, написанных на electron. Мягко говоря не самая типичная обертка для игрушек, а получилось очень даже отлично.

                Я не говорю, что без движка нельзя сделать вообще или что нельзя сделать лучше. Можно. Но движок позволит сделать то же самое с меньшими усилиями и существенно сэкономив время.
                  0
                  А никто и не говорит про навороченный движок. Просто актуальный движок.

                  Про навороченность я помянул в контексте того, что если автор хочет сам поразбираться, и запросы у него простые — очень даже можно и самому поразбираться. И только если запросы большие и растут — тут да, можно однозначно сказать, что если не взять готовое, то вся работа так и останется на уровне бесконечного допиливания собственного движка.
                +2
                Спасибо за совет. Мне интересен не сам результат в виде готового продукта — игры, а пройденный в процессе путь. Я знаю людей, которые взяв движок смогут его эффективно его использовать, будучи совершенно незнакомыми ранее.

                Но есть и такие как я: для меня использование системы, тонкостей которой я не понимаю, полно сомнений, а значит ошибок. Как пример CAD для математики — ок, а Blender сейчас — боль. Всё потому что я не понимаю пока, как устроена CG.

                PS ну ладно, ладно, я всё же хочу выпуска игры, денег, славы и мирового господства, хе-хе.
                  0
                  А вы думаете, что написав игру на фреймворках, затем сможете эффективно работать с тем же Unreal? Вовсе нет. Это до какой-то степени улучшит ваше понимание конвейера (а вообще, кто сказал, что там будет что-то похожее на то, что делали вы? ведь вероятность того, что вы сразу сможете организовать грамотную архитектуру, почти нулевая), но не более того. Движок точно так же придётся учить с нуля. И чем быстрее начнёте, тем быстрее достигнете качественного результата. Не теряйте время зря. Что вы почувствуете, потратив, например, 3 года на разработку, после того, как вам скажут, что то же самое можно было сделать за пару месяцев, а почти все полученные знания — бесполезны?

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

                  P.S. Самый эпичный случай, из тех, с которыми сталкивался лично, был, наверное, когда старший разработчик одного из проектов потратил три месяца на разработку, а после выяснилось, что ровно то же самое можно сделать другими средствами за день.
                    0

                    Окей, отвечу более предметно:
                    1) Готовый движок не научит меня проектированию библиотечного кода на ++
                    2) Готовый движок не научит меня проектированию клиентского кода на ++
                    3) Готовый движок лишит меня радостей жизни, таких которые были описаны в статье.


                    Утверждение о том, что мои 3 года разработки можно уложить в то же самое очень сильное. Вы же не знаете, о чём идёт речь и что будет через 3 года.


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


                    Что будет, если вообще игра не получится? Не жалейте моего времени.
                    Лучше дайте ссылки на движки, которые пилят 10 лет.

                      0
                      Что вам мешает делать тоже самое на каком-то готовом движке?
                      Я вот изучаю Godot и там целый мешок есть чего написать в проект на ++, и радостей жизни лишён не будешь. Тот же оклуд и ЛОДы ждут своего героя.
                0
                Я думаю, у Вас применение TDD упирается в слабую абстрактную модель проекта. Я конечно скажу банальщину, но постарайтесь провести декомпозицию на каждом рассматриваемом уровне, естественно с выделением интерфейсных частей.
                  0

                  У вас есть опыт TDD именно в геймдеве? Расскажите, я бы послушал. Серьезно.

                    0

                    Я полностью согласен про модель. Это навык, который я стараюсь развить. Тем не менее для меня RnD = "нестабильные интерфейсы". А последние делают тесты хрупкими.

                    0
                    Отличная статья! И очень правильная идея писать движок с нуля, а не брать готовый, многое перестает быть загадкой если придется взять Unity или Unreal. Сам проходил похожий путь год назад с Opengl/assimp/imgui/glm, правда обертка у меня была SDL2. Не хватило терпения дойти до чего-то играбельного, понял что тянет ковырять графическое апи и шейдеры и всё свободное время ушло в развитие и рефакторинг движка, а не самой игры. Так что автор молодец раз не остановился, обязательно продолжай!

                    Конечно же я скачал код и собрал. Пришлось исправить место где идет обращение ко «второму» монитору, у меня он всего один =), но игра завелась и подгрузились ресурсы с шейдерами. Нашел способ превратить плоскую планету в сферу и вращать планету через зажатую среднюю кнопку мыши, но дальше дело не пошло. Может есть какой-то гайд? Уж очень хочется оценить геймплей.
                      0

                      Будет README. Что до геймплея, им займусь после работы над движком, если так его сейчас можно назвать.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое