Или как добиться большего на следующем вашем хакатоне
Некоторое время назад я принимал участие в ежегодном игровом мероприятии Itch.io Game Off 2020, участники которого за ноябрь делали игру на определённую тему. Тема этого года, Moonshot, привела к созданию более 500 амбициозных, в основном космических, игр, которые вы можете увидеть здесь.
Услышав о мероприятии в октябре, я рассказал о нём своему брату и его жене, и мы решили объединиться в команду. Мы ни в коем случае не разработчики игр, но наши личные навыки хорошо дополняли друг друга. Жена брата, художник, сосредоточилась бы на создании ресурсов для игры. Тем временем мой брат, аниматор, ставший программистом, и я, программист, сконцентрировались на создании игры.
Как только стала известна тема, мы сразу же начали мозговой штурм, чтобы придумать идею, которая, в духе темы игрового соревнования, будет весёлой, амбициозной и желательно космической.
У нас было несколько идей, но одна заставила нас возбуждённо кивать во всеобщем согласии, это была идея игры Bad Asstronauts. Посыл игры была таким:
Bad Asstronauts — это динамичная многопользовательская мобильная игра, в которой игроки на вооружённых космических кораблях рыщут по космосу в поисках ценных ресурсов, накапливаемых кораблями на их родных планетах. Игроки всё время должны защищать свой тайник с ресурсами от уничтожения противниками.
Изначально выбранное для статьи название было таким: «Создание многопользовательской игры в реальном времени за 30 дней». Видя, как мы разрабатываем игру, я хотел поделиться с вами некоторым опытом, который мы извлекли за эти 30 дней, создавая игру в условиях ограниченного времени.
Понимание требований проекта
Определившись с тем, какую игру мы хотим создать, мы задались вопросом, о том, какие технологии использовать. Поскольку мы создавали многопользовательскую игру, это решение нужно было принять относительно внешнего интерфейса и относительно серверной части — оба решения раз и навсегда.
Без особой причины мы решили попробовать свои силы в создании интерфейса с помощью Flutter, используя Flame, минималистичный движок для 2D-игр. Для нашей игры этот выбор казался разумным. Серверная часть, однако, окажется сложнее. Многопользовательские онлайн-игры заведомо сложны в разработке, и компонент реального времени, который нам хотелось воплотить в жизнь, только усугубил бы эту сложность.
Нашим первым подходом было использование Firebase, учитывая её популярность в сообществе Flutter, её кажущуюся жизнеспособность в играх и рекомендации друга. Итак, мы решили сделать небольшую проверку концепции, чтобы проверить идею.
Тест синхронизации данных с WebSocket
Не упускайте из виду главную задачу
К сожалению, то, что должно было закончиться за несколько дней, продлилось до середины ноября. Хотя настроить и запустить Firebase было непросто, главным пожирателем времени было кое-что другое — отвлечение внимания. На реализацию того, что вы видите на гифке выше, у нас ушло несколько дней. Из этого мы извлекли урок: бессерверный подход Firebase с Cloud Functions и Firestore (один из двух вариантов облачной базы данных) хотя и полезен во многих ситуациях, но не сможет удовлетворить требованиям к игре в реальном времени, которую мы предполагали создать.
Жаль, что вместо того чтобы сразу создать то, что вы видите выше, мы увлеклись попыткой создать мини-игру, в которой будут соревноваться два игрока, чтобы увидеть, кто получит наибольшее количество кликов, не забыв о хранилище, прежде чем истечёт таймер. Это включало внедрение совершенно ненужных функций, таких как таймер, счёт и цвета: все они не имели никакого смысла, когда дело доходило до выяснения того, жизнеспособна ли Firebase.
Вскоре после этого мы перешли на WebSockets, но время, потраченное на работу над всеми этими не имеющими отношения к делу функциями, ушло. Наша ошибка здесь была в том, что мы упустили из виду главную цель и раньше не задались вопросом о том, как всё это помогает нам её достичь. Итак, постарайтесь быть максимально целеустремлёнными, держите в голове одну мысль. Свистелки и крутилки можно добавить позже.
Не экономьте на исследованиях
Нельзя сказать, что с фронтендом все шло гладко. Точно так же, как Firebase выполняет большую часть тяжёлой работы за вас на серверной части, использование игрового движка позволяет вам взяться за дело, предоставляя множество инструментов из коробки: игровой цикл, рендеринг объектов, физику — список можно продолжить. Если, конечно, вы используете эти инструменты.
Хотя мы пользовались многими инструментами, которые предлагал Flame, мы в конечном счёте реализовали многое самостоятельно. Не потому, что реализация во Flame была неадекватной, а просто потому, что мы не знали о её существовании! Стремясь приступить к работе, мы быстро прошли через самый важный этап — этап исследования. В результате мы создали множество компонентов с нуля, не зная, что они добавлялись инструкцией import.
Яркий пример — джойстик, для которого у Flame был отличный модуль. Вместо этого мы сделали свой собственный, что (не поймите меня неправильно) было прекрасной практикой, но, возможно, не лучшим применением времени в плотном графике. Мы делали то же самое с другими компонентами, и очень скоро стало ясно, что, изобретая колесо, вы часто получаете квадрат.
Поспешные решения, которые мы разработали, сделали проект очень сложным в работе и расширении (это действительно о чём-то говорит, если вы занимались им всего пару недель!). Это побудило нас сделать шаг назад и переделать многое из того, что у нас уже было, но на этот раз с применением как можно большего количества встроенных реализаций, которые предлагал движок.
Перестройка, безусловно, заняла некоторое время, прежде чем началось внедрение новых функций (около пары дней), но по окончании уже можно было сказать, что мы продвигались гораздо быстрее. Здесь нужно помнить, что даже несколько минут исследования могут сэкономить вам часы ненужной работы в будущем.
Знайте свой инструмент
В связи с этим поиск эффективного рабочего процесса имеет решающее значение для быстрой разработки функций и прототипов. Одним из основных препятствий, мешавших нашему прогрессу, было то, что нужно было протестировать код на нескольких клиентах, чтобы убедиться, что сетевые функции работают должным образом.
Для этого потребовалось запустить несколько эмуляторов Android, которые, как известно всем, кто с ними работал, представляют собой голодных до памяти зверюшек, при работе с которыми даже на приличных машинах ресурсов будет не хватать. Однако из-за отсутствия плана лучше мы терпели — даже когда символы появлялись в редакторе кода с такой скоростью, как если бы мы печатали их с другой планеты. Но был способ получше.
Flutter, будучи кросс-платформенным набором инструментов, позволяет создавать приложения для веба из той же кодовой базы, что используется для мобильных устройств. По сути, это означало для нас, что мы могли полностью обойти эмуляторы и вместо этого запускать несколько клиентов прямо из браузера со значительным снижением затрат памяти. Вот только нам довелось сделать это грандиозное открытие намного позже, и, по большей части, когда приходило время запускать тесты на нескольких клиентах, нам приходилось мириться с убивающим поток положением дел.
Я не говорю, что вам нужно знакомиться с каждым укромным уголком каждого инструмента, который вы используете, но это, может быть, один из немногих случаев, когда достоинством является неудовлетворённость, а не терпение. В тот момент, когда вы начинаете задаваться вопросом, есть ли лучший способ сделать что-то, сделайте себе одолжение и проверьте, существует ли он. Обычно он существует и может принести выгоду.
Рассмотрите подход к работе слоями
Одна из вещей, которую мы сделали в самом начале, — мы применили многоуровневый подход, когда дело дошло до добавления новых функций в игру. В этом смысле слой — это не что иное, как набор функций, которые в сочетании с функциями из лежащих ниже слоев составляют полнофункциональную версию того, что вы делаете.
Преимущество подхода заключается в том, что, если команда в какой-то момент заметит, что не сможет завершить функции текущего слоя до истечения крайнего срока, она может вернуться к предыдущему слою, при этом останется возможность возможность выполнить работающий, завершённый проект. Например, вот слои, определённые для нашей игры в начале:
План разработки высокоуровневых функций для Bad Asstronauts с 7 уровнями сложности
Причина случившегося проста. По мере увеличения числа функций в приложении растёт и уровень сложности. Если оставить это без внимания, возрастающая сложность может привести к тому, что разработка проекта выйдет из-под контроля, что приведёт к значительным задержкам или даже отмене проекта. Это явление известно как «скрытая функция».
Это то, что мы в любом случае надеялись получить от многоуровневого подхода. Однако по разным уже упомянутым причинам поднять даже первый слой с земли, то есть слой с базовыми функциями, заняло больше работы, чем можно сделать в заявленный 30-дневный срок.
Тем не менее это не должно снижать его эффективность при правильном применении и в сочетании с другими упомянутыми здесь моментами. Это подводит меня к моему последнему пункту.
Не откусывайте больше, чем можете прожевать
Ни один из пунктов, упомянутых до сих пор, не принёс бы особой пользы, если бы цель с самого начала была слишком амбициозной. Мы все стремимся превзойти самих себя, и это замечательная черта, которую нельзя игнорировать. И, хотя наши амбиции могут быть бескрайними, время и энергия, ресурсы, которые управляют нашим стремлением к этим амбициям бесконечными быть не могут.
Для команды из трёх человек с ограниченным опытом создания игр в принципе решение создать игру предполагаемых масштабов, с возможностями многопользовательской игры в реальном времени всего за 30 дней, возможно, было немного перебором. Например, стратегией разумнее было бы пойти на компромисс и выбрать либо относительно сложную однопользовательскую игру, либо многопользовательскую игру попроще.
Итак, перед началом оцените усилия для реализации каждой предложенной идеи — это ключ к обеспечению плавного процесса разработки. Оценка усилий увеличит ваши шансы воплотить задуманное в необходимые сроки. Продолжайте разрабатывать! Помните: законченное лучше идеального.
- Профессия Java-разработчик
- Профессия Frontend-разработчик
- Профессия Веб-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРСЫ
- Курс по Machine Learning
- Продвинутый курс «Machine Learning Pro + Deep Learning»
- Курс «Python для веб-разработки»
- Курс по JavaScript
- Курс «Математика и Machine Learning для Data Science»
- Курс по аналитике данных
- Курс по DevOps
Автор: one-two