Как я более года разрабатывал игру для Fortnite, пытаясь осуществить мечту детства
Около недели назад я запустил свой собственный остров в Fortnite, над которым работал более года. Скорее всего это сложно назвать полноценной игрой, но, тем не менее, для меня это был первый шаг в геймдев. В этом лонге я хотел бы рассказать о процессе разработки, сложностях, с которыми столкнулся, и поделиться первыми впечатлениями. Я буду немного перескакивать по этапам, чтобы история получилась более цельная. По какой-то причине в статье пропали картинки и часть текста, а при попытке исправить выдавало ошибку. Добавил заново :/
Мир игр я для себя открыл еще в детстве, когда родители подарили мне Super Nintendo и пару картриджей, которые я затер до дыр. Среди игр были Donkey Kong Country и Doom Troopers: The Mutant Chronicles, которую я так и не осилил в то время. SNES во дворе почти ни у кого из парней не было, поэтому меняться картриджами, считай, было не с кем. Как раз тогда примерно начал выходить журнал “Страна Игр”, первые выпуски которых до сих пор пылятся где-то у родителей. В статьях писали не только о самих новинках, но и немного о разработчиках, выставках и прочем. Тогда я впервые заинтересовался не только тем, какие выходят игры, но и как они сделаны. Даже пару раз писал письма в журналы, но они не были опубликованы в колонках читателей.
Чем старше я становился, тем больше интересовался разработкой игр, но это была сфера, далекая от меня. Потом случился переезд в Японию на обучение, где я в итоге и остался. Геймдев и все, что с ним связано, осталось для меня просто хобби. Я читал различные статьи, смотрел видео о разработчиках, но на этом все. Помню, как с удовольствием читал о Даниэле Вавре, создавшем одну из моих любимых игр Mafia: The City of Lost Heaven.
Тем не менее, мечта когда-нибудь создать свою, пусть и простенькую, игру, теплилась во мне все эти годы. В разное время я устанавливал и пробовал Unity, Unreal Engine, Renpy и RPG Maker, но дальше тыканья по менюшкам я не заходил. К сожалению, я понимал, что у меня нет нужных навыков для начала разработки, а языки программирования, которые я изучал в университете, просто были для меня бесполезны. Basic, QBasic, Delphi и еще парочка, которые я уже просто-напросто забыл. В общем, я не умел рисовать, не знал 3D моделирование и программирование. Во всяком случае, я так сам себя оправдывал, ведь, было бы желание, всему можно научиться.
Жизнь шла своим чередом и вот, мне уже почти 36 лет. В один из дней случилось выгорание и накатила какая-то усталость от всего, что я делаю. Возможно это кризис среднего возраста, но тем не менее. И я подумал - почему бы не сделать паузу и не заняться тем, что я давно откладывал в долгий ящик. Так и поступил.
Проблема с отсутствием необходимых для разработки знаний никуда не делась, и я решил начать с того, что на данном этапе мне под силу. Изучив различные варианты, я решил попробовать создать свой собственный остров в Fortnite. Почему бы и нет, если да. В Fortnite люди создают как откровенный шлак, так и вполне себе отличные инди-игры.
Пролистав сайт Epic, я узнал для себя, что есть два варианта разработки игры внутри Fortnite.
Первый вариант - это Creative 1.0, где вы все делаете прямо внутри самой игры, расставляя вашим персонажем модельки, связывая различные устройства и так далее, но при этом с большим количеством ограничений. По сути, что-то сложное там сделать практически невозможно, лишь то, что позволяют системы, задуманные самими разработчиками Fortnite.
Другой вариант - это Unreal Engine for Fortnite, он же UEFN, он же Creative 2.0. Если говорить простыми словами - это урезанная версия Unreal Engine 5, заточенная под разработку островов в Fortnite. В отличие от Creative 1.0, там есть возможность добавлять собственные 3D модели, звуки, материалы и, что самое главное, писать код, создавая устройства, которые нет в Fortnite. Все ограничено лишь воображением разработчика. Для себя я выбрал как раз UEFN, к тому же, я как раз купил ПК на Windows с хорошими характеристиками.
Установив программу, я начал потихоньку в ней разбираться. Казалось, что возможности безграничны: делай, что хочешь. Увы, я быстро понял, что это не так, но обо всем по порядку.
Язык программирования Verse
В UEFN код пишется на языке программирования Verse, который был специально разработан для создания метавселенных в Fortnite. Как я уже сказал, программирование я не знал, хотя незадолго до этого прошел начальный курс по C++, поэтому начал изучать Verse с самых основ. Мне сложно понять, на что он похож или чем отличается от других языков, но я быстро понял, что написать что-то на нем - это та еще морока. Он не особо логичный и заточен под Fortnite, поэтому все, что пишется на нем, так или иначе связанно с игроком, готовыми устройствами, статусами и событиями. В начале у меня вообще мало что получалось, но я решил, что сначала попробую написать свою собственную валюту для игры, чтобы не использовать стандартные монеты Fortnite.
Я разобрался, как создать текстовый блок, как добавить картинку, которая лежит в папке игры, как менять значение и прочее. На все это у меня ушло больше недели, чтобы сделать что-то такое простое. Раз за разом я перечитывал курс по Verse на сайте самого Epic, пытаясь хоть в чем-то разобраться. Начал смотреть ролики других разработчиков, которые рассказывали, как и что работает, как подписаться на события устройств и где посмотреть возможные команды. Казалось бы, вроде, все понятно, но потом компилируешь, а там ошибок больше, чем строк в коде. Да как так-то?! Процесс шел медленно, поэтому я решил отвлечься и подумать над тем, что мне вообще хочется создать внутри Fortnite.
Ферма в Fortnite
Я еще раз посмотрел, какие острова делают другие разработчики. Либо это просто пострелушки, оформленные максимально просто и однотипно, либо тайкуны, где игроку нужно просто нажимать по порядку кнопки разной стоимости, а для зарабатывания денег покупать устройства, которые раз в секунду приносят какую-то сумму денег. По сути, что-то вроде Cookie Clicker с разными вариациями. Один разработчик вообще перенес в Fortnite игру Phasmophobia, причем, очень хорошо получилось. Но у всех этих игр не было истории и живых персонажей, в основном только механики. С другой стороны, среди островов есть множество хоррор-игр, но они все на один раз. Мне хотелось создать что-то такое, куда игрок захочет вернуться, но с душой и большей глубиной. В итоге, я решил сделать симулятор фермы, так как в свое время наиграл сотни часов в Stardew Valley, и такой формат мне нравился.
Я начал думать. Что должно быть на ферме? Выращивание овощей, различные животные, возможно, строительство и персонажи, с которыми можно пообщаться. В общем и целом понятно, но как это сделать? Первая проблема, с которой я столкнулся, это создание системы роста овощей по стадиям. Вроде, звучит просто: посадил - 1 стадия, через какое-то время 2 стадия, а затем 3 стадия, которую игрок собирает и получает ресурсы. Но как же я намучился с этим! В момент начала разработки у обычного меша не было функции “показать/скрыть”, поэтому для этих целей необходимо было использовать специальное устройство prop manipulator device, которое позволяло по сигналу показать или скрыть 3D модельку овощей. Я около месяца писал свое первое устройство для роста овощей, но, закончив, понял, что у меня получается монстр.
Чтобы отслеживать стадии роста, я, поначалу, использовал встроенный timer device, но оказалось, что он криво работает. Я хотел, чтобы по завершению таймера он перезапускался и начиналась 2 стадия роста, но он просто не перезапускался или перезапускался, но стадия не менялась. В итоге, я поставил 2 таймера, на каждую из стадий, а также по 3 prop manipulator device на каждый проп овоща. А еще кнопку (button device) на посадку и сбор урожая. Но я также хотел дать возможность удобрять грядки, а это еще одна кнопка. А теперь возьмем все это, масштабируем под большее количество грядок, под разные овощи, и получаем сотни устройств. Геморно, конечно, но я тогда думал - главное, чтобы работало хорошо. Но нет.
Ограничение по памяти
Fortnite доступен на всех консолях, ПК, в облачных игровых сервисах и на мобильных устройствах. Необходимо, чтобы каждый остров одинаково хорошо работал везде, поэтому разработчики из Epic ввели ограничение на общее количество памяти, которую можно использовать. Максимум может быть 100 000 памяти. Но что это за память? Это не вес 3D моделей или изображений, а суммарное количество памяти, которое занимают все модели, устройства, кнопки и написанный код в окружении игрока на определенной клетке. Образно говоря, поставили модельку бочки - сразу минус 100 памяти. Написали код и разместили его в сцене (он выглядит как компьютер) - еще плюс память.
Я понял, что мой код овощей просто жрет всю память, так как он грузный и сложный, надо упрощать. Чего я только не перепробовал, думал даже уже сократить количество стадий роста, но решение пришло от самих разработчиков Epic. Они дали возможность через код Verse скрывать и показывать обычные пропы, без использования дополнительного устройства. Также я научился через код менять текст на кнопке, так, чтобы одна кнопка была и для посадки, и для удобрения, и даже для покупки самой грядки. Я заменил устройства таймеров на обычные текстовые девайсы (billboard device) и просто через код менял в них текст, создавая таймер вручную. Тем самым я смог сэкономить много памяти.
Но проблема с нехваткой памяти никуда не делась даже сейчас, когда я уже опубликовал остров. Это моя самая большая головная боль. Оказалось, что, если размещать устройство, то оно в любом случае занимает память, где бы игрок не находился. А если вы связали какую-то 3D модель с кодом, то и она будет тратить память в любом месте. Сам ландшафт карты также использует все ту же память. Я долго ломал голову над тем, как бы решить эту проблему, и открыл для себя Data Layer.
Data Layer
Data Layer - это такие слои данных, куда вы можете добавить различные 3D модели и все, что не связано как-то с кодом, загружая в тот момент, когда объекты находятся в поле видимости игрока. Идея, вроде, понятна, и вот оно решение. Но, опять же, нет. У меня на карте есть пляж, город, ферма, кемпинг, лес, пещера и другие локации. Я подумал, что, если я просто буду выгружать и загружать нужные локации, когда в них находится игрок, то это решит проблему с памятью. И действительно, я смог опустить со 103 000 до 84 000! Победа! Я продолжил делать остров, понимая, что, в крайнем случае, еще уменьшу количество используемой памяти, если буду, к примеру выгружать часть фермы, которую не видит игрок. К слову, выгрузка слоев тоже работает максимально тупо. Нет возможности это сделать через код или каким-то специальным устройством. Единственный рабочий вариант, который я нашел, - это использовать секвенсер для анимации, где 0 кадр - выгружено, а 1 кадр - загружено. Работает и ладно, думал я, но радость моя была недолгой.
Когда остров был почти закончен, я залил приватную версию, чтобы проверить, как все системы работают в мультиплеере, и обнаружил, что моя идея провальная. Оказалось, что загрузка и выгрузка локаций только глобальные, их нельзя сделать индивидуальными для каждого игрока. Получилось, что два игрока прибежали в город, все прогрузилось, но когда один из них ушел, то и город пропал, оставив другого игрока в чистом поле. ААААААА! Вот такая была у меня реакция, и я начал дальше думать, что можно сделать. Прочитал в документации, что можно отлавливать местоположение игрока и выгружать только в тот момент, когда все игроки вышли из области, но это не сильно помогло. Работало через раз и было просто неиграбельно. В итоге я решил ничего не выгружать, а просто упростить карту и дальше занялся облегчением устройств.
Вернусь немного назад к процессу разработки. Вместе со мной над проектом работала моя жена Анастасия, у которой, как и у меня, не было необходимых навыков. Мы все делали методом тыка. Она взяла на себя, по большей степени, обустройство фермы. Расставляла объекты, делала ландшафт, а также продумывала лор и персонажей. Я же со своей стороны делал всю техническую часть, также продумывая персонажей и квесты. В основном мы использовали 3D модели, которые есть в самом UEFN, а также брали бесплатные ассеты из открытых источников или с подходящей нам лицензией. Некоторые модели сделали сами. В процессе разработки немного освоили Blender, научившись создавать скелеты и анимировать животных. Пришлось использовать Low Poly животных и растения, так как, опять же, над нами висело ограничение по памяти.
Для интерфейсов использовали встроенный в UEFN UMG редактор, который позволяет создавать UI. Но он тоже очень глючный и урезанный. Оказалось, что, если я хочу, чтобы при нажатии кнопки “купить” что-то делалось в коде, к примеру, начислялись семена кукурузы, то я просто не могу этого сделать. Интерфейсы и код вообще никак не связаны, из Verse просто нет доступа к UMG.
Я нашел решение, но это был максимальный костыль: оставить кнопки просто картинкой и сверху через код рисовать на них невидимые хитбоксы под размер кнопок. И все сработало! Я сделал так все интерфейсы, потратив кучу времени, но оказалось, что на них можно нажать только мышкой, а контроллеры эти хитбоксы просто не видят, так как у них нет фокуса. ААААА! Снова подумал я, и начал искать решение. И оно нашлось - сделать не хитбоксы, а прямо кнопки через код (тогда было 3 вида кнопок в UEFN, сейчас 4), на которых можно фокусироваться, и тогда получится их нажать с контроллера. Но проблема в том, что все эти кнопки с дизайном, который перекрывает изображение кнопки в UI. Я могу к ним через код прицепить картинку кнопки, но тогда она перестает нажиматься с контроллера. В общем, я очень долго с этим парился и остановился на полупрозрачных кнопках. Да, они частично закрывают изображение, но это лучше, чем ничего. И как только я закончил, разработчики выпустили обновление, добавив в UMG для создания интерфейсов Variables, через которые можно связать интерфейс с кодом. Очень вовремя, спасибо. В итоге я в третий раз переделал все интерфейсы, но теперь это стало похоже на то, что я изначально хотел видеть.
Наша ферма постепенно начала принимать очертания чего-то цельного. Я сделал инвентарь, где хранятся все ресурсы игрока: овощи, удобрение, корм для животных и прочее. Чтобы сохранять все ресурсы игрока между сессиями, разработчики советуют использовать stat creator device - специальное устройство для хранения параметра (1 на 1 ресурс). Я сделал их около 40 штук на все ресурсы, и тут меня снова ждало разочарование. Оказывается, если их разместить более 15 штук (выяснил методом проб и ошибок), то они начинают дублировать друг друга. Т.е. количество удобрений записывается в кукурузу и так далее, причем, совершенно рандомно. Про это вообще нигде нет информации в документации, но пришлось отказаться от этих устройств и делать все через код, на что я потратил несколько месяцев, так как начал изучать систему сохранений игрока с помощью Verse, чтобы собранные ресурсы не удалялись между сессиями. Долго мучился, но сделал.
Приватная версия VS Edit Mode
Следующая проблема была в приватной версии. Чтобы проверить работу острова и кода, необходимо залить приватную версию в сам Fortnite. Я не делал этого почти всю разработку, так как думал, что сначала надо сделать цельную структуру, а потом проверять. Это было ошибкой. В самом UEFN есть Edit Mode, позволяющий запустить ваш остров внутри Fortnite, но как бы с вашего компьютера, а не с их серверов, хотя остров все равно подключается, как при обычной игре. Оказалось, что сохранения между сессиями нормально там не работают. Я долго переписывал код, думая, что что-то делаю не так, а оказалось, что оно просто не сохраняет в этом режиме. Также нельзя проверить мультиплеер, только в одиночку, даже если у вас в команде кто-то есть. Этого достаточно для простых проверок, но если нужно узнать, как остров покажет себя после публикации, то нужно именно заливать приватную версию. Но мне просто не дали этого сделать!
Чтобы появилась возможность залить приватную версию, необходимо пройти проверку и соответствовать требованиям, главные из которых - это иметь аккаунт старше 30 дней и использовать UEFN 7 дней в течение последнего месяца. Первое условие я выполнил, а второе у меня было 0/7. Я год работал, ау! Я написал в поддержку Epic, которые просто дежурно мне ответили “продолжайте работать”. Я продолжил, но все равно все было по нулям. Советы с reddit не помогли, все перепробовал. Но я, все-таки, нашел решение. Надо было создать новый остров именно в режиме Creative 1.0 и работать над ним с компьютера или консоли. Вот так я целую неделю заходил с PS5 в этот режим и ставил домики, удалял их, связывал устройства и просто создавал активность. О, чудо! Стало 1/7!
Перед релизом
Прошло больше года, я сделал основные механики, все отполировал, и это работало, вроде, хорошо. Но из-за особенности моего проекта, сохранения игроков перезаписывали прогресс друг друга. Если вы играли в тайкуны в Fortnite, то, наверное, знаете, что почти все делают так, что у каждого своя “база” на карте. Другими словами, разработчики делают 4 одинаковых локации в разных частях карты, и каждый проходит как бы один, просто с другими игроками в онлайне. У каждого свой прогресс, а у меня была идея общей фермы, где все грядки, животные, дом и прочие локации - общие, а свои только ресурсы. В UEFN почти нет настроек per-player, почти все глобальное. Если я хочу включить или выключить кнопку, то это можно сделать только для всех. Я понял, почему все делают острова именно так, но не сдавался и еще больше месяца переписывал систему сохранений.
Я решил сохранять всем игрокам весь прогресс и отдельно записывать статус мира. Получилась сложная система, но она работала. Однако появилась уже другая проблема.. Из-за постоянных сохранений стадий роста, грядок, производств животных, квестов, ресурсов и еще кучи всего, игра просто начала подтормаживать. Произвела корова молоко - всем игрокам записалось, но в эту же секунду выросла кукуруза или игрок собрал древесину, что тоже записалось в память, отчего игроков начинало дергать, словно при высоком пинге. Чего я только не пробовал, становилось не многим лучше, а у меня уже начал глаз дергаться от того, как меня это все бесит. В итоге я решил проблему тем, что создал очередь сохранений. Одновременно никогда ничего не сохраняется, только по очереди. И, о чудо! Это решило проблему, но заняло еще несколько недель.
После сотен приватных версий, миллиона чашек выпитого кофе и бессонных ночей, мы, наконец-то, смогли получить игру, подходящую для релиза. Мы опубликовали остров 8 апреля. За это время в нашу ферму поиграли 222 раза, в основном мои подписчики, а также люди, узнавшие об острове за счет пары постов на reddit. Проблема в том, что остров почти никому пока не показывается, так как Epic его еще проверяют. К примеру, еще не включили опыт на острове, чтобы игроки могли качать боевой пропуск. Чтобы заработал опыт и карту начали показывать игрокам, они должны собрать статистику, а сколько это времени займет - неизвестно. Другими словами, если я сам не приведу игроков, то в остров так никто и не поиграет. Если игрокам понравится, то тогда, возможно, его начнут показывать и рекомендовать. Я даже не могу просмотреть полную статистику, так как нужно 5000 показов, а их просто нет. Все заходят на остров напрямую по коду. Тем не менее, среднее время, которое игрок проводит в игре, на данный момент, составляет 54 минуты, что, на мой взгляд, хорошо. Посмотрим, что будет дальше.
Разработка шла больше года, а все остальные дела я поставил на паузу, так как хотел осуществить свою мечту с детства. Да, это не полноценная отдельная игра, но это только начало. Я рад, что жена меня в этом поддержала и сильно помогла с разработкой. Как бы там ни было, это невероятное чувство, что проект удалось довести до конца! За это время я многое узнал о разработке игр, поднаторел в программировании на Verse, изучил UEFN и многое другое.
Мы старались создать уютную добрую ферму со спокойным геймплеем, где игрок сможет просто отдохнуть от работы. У нас есть разные персонажи, записки, диалоги и квесты с историей. Перевели ферму на 4 языка вручную, а на остальные есть машинный перевод. Оставили пасхалки, которые поймут только русскоговорящие игроки. И впереди планируем дополнения, которые как расширят существующие механики, так и добавят новые. Правда, для начала надо решить, что делать с памятью, ведь на релизе занято 94 000 из 100 000.. Но это потом, а пока я просто рад, что все получилось.Я не стал описывать еще кучу сложностей или забавных моментов, с которыми столкнулся в процессе разработки, так как лонг получился итак долгим, но если вам будет интересно, то напишу потом продолжение.
Если вы играете в Fortnite и вам интересно посмотреть, какой остров у нас получился, то будем рады, если зайдете к нам на ферму, поиграете и оставите отзыв, что поможет улучшить игру.
Код острова: 9069-8344-8701
Спасибо за внимание.