
Приветствую, дорогие читатели! Так получилось, что я решил попробовать себя в разработке игр, не ради заработка или написания самой‑самой видеоигры в истории, а просто в рамках хобби. И вот после почти 18 месяцев разработки у меня есть что‑то, что можно с натяжкой назвать игрой и опыт, полученный на ошибках.
В игре ещё есть над чем работать, но, к сожалению, я немного перегорел этим проектом — теперь есть желание попробовать разработку на современном движке и разработать что‑то не пошаговое, а более линейное. А свою первую игру я хотел закинуть «в стол», но решил, чтобы добро не пропадало, написать статью. Дать несколько советов на основе полученного опыта. Возможно, это поможет кому‑то сделать свою игру мечты, или поможет избежать моих ошибок, или просто развлечёт вас.
Посмотреть игру и понять, нужно ли вообще читать это дальше, можно вот тут:
http://f1 136 045.xsph.ru/ — Там бесплатный тестовый домен, так что не удивляйтесь предупреждения от браузера:‑)
Первый шаг
Интернет говорит, что создание игры должно начинаться с написания диздока.
Я решил не отступать от проверенных практик и тоже накидал дизайн‑документ, но по ходу разработки понял, что какие‑то механики слишком сложно реализовать, какие‑то конфликтуют друг с другом, что‑то не имеет смысла, а что‑то делать мне будет просто лень.
Поэтому первоначальный концепт пошаговой рпг с системой диалогов, несколькими концовками, несколькими фракциями и возможностью достичь цели разными способами превратился в rogue‑lite с противостоянием трёх фракций, захватом секторов и упором на билдостроение.
Если вы дочитали до этого момента, думаю, вы одобрите отказ от диалоговой системы, ведь диалоги тоже были бы написаны мной! Решение по максимуму сократить писанину повлекло за собой и сокращение других элементов. Я всё же потратил какое‑то время на написание первоначального диздока, который по итогу оказался нафиг не нужон. Поэтому, возможно, иногда не стоит упарываться с написанием подробного и всестороннего дизайн‑документа.
Приведу случаи, когда диздок всё же нужен:
Вы разрабатываете игру не в одиночку. При командной разработке всем нужно на что‑то опираться и иметь в голове некий завершенный вариант игры. В такой ситуации чем подробнее первоначальное описание, тем меньше ошибок сделает каждый участник команды;
Вы хотите игру в устоявшемся жанре и не планируете пускаться в эксперименты с механиками. Если вы создаёте шутер или рпг, то основные отличия от других игр в жанре у вас будут в сюжете, дизайне уровней, противниках и т. д. Если вы, к примеру, планируете сделать игру с сюжетом про противостояние добрых пони и злых пони и геймплеем DOOM — вам нужен диздок;
Вы планируете привлечь сторонние инвестиции или продать идею своей игры.
Если же вы планируете замутить что‑то инновационное, у вас есть идеи механик, которые раньше не использовались или уникальное сочетание известных механик, то прописывать досконально диздок не нужно, лучше вместо этого поскорее сесть за разработку прототипа. Пусть геймплей рассудит, какая должна быть игра. Но перед началом разработки одну вещь лучше сделайте обязательно — определитесь со стилем.

Отталкиваясь от стилистических рамок, вы сможете прикинуть, какие готовые ассеты можно взять, какие нужно будет создавать самостоятельно, а от чего в игре вообще нужно отказаться. Ну и если всё в игре выдержано в одном стиле, то сама игра выглядит намного лучше, я бы даже сказал «дороже», а не как ассет‑флип, собранный за пять минут. Как понимаете, момент с выбором стиля я тоже успешно провалил, но для того и нужна эта статья, чтобы с вами такого не было :‑)
Движки
Я решил разрабатывать свою игру на чистейшем как слеза js. Это было ошибкой. Не повторяйте моих ошибок — используйте готовый движок или даже конструктор игр. Да, у движков есть проблемы с производительностью, с функционалом, который вам не нужен, но который всё равно будет тянуться с движком и занимать место и т. д.
И всё же я считаю, что лучше собрать прототип игры на готовом движке. Потом, при необходимости, можно переписать всё без использования движка или провести оптимизацию.
Лично я следующую игру планирую делать используя что‑то из тройки Unreal Engine, Unity, Godot. И раз уж речь пошла про экономию времени и облегчение труда, перейдём к следующему пункту.
Пара слов о нейросетях
Изначально план был нагенерить изображений через нейросеть (ХАЙП!!!)

У нескольких блогеров мне тогда попадалась реклама нейросети Кандинский (не реклама, дальше поймёте почему), но на тот момент (а возможно и сейчас, когда вы это читаете) нейронки не очень подходили для генерации спрайтов для игр, так что я использовал Inkscape, точнее моя супруга, которой я делегировал допиливание моих эскизов и создание спрайтов с нуля.
На момент начала разработки у генерации было несколько проблем:
1. Цензура. Мы даже не разрабатывали игру для взрослых, но столкнулись с отказом генерации в случаях, когда промпт содержал такие слова, как: «пушка», «миномёт», «гранатомёт», «ракетная установка», «истребитель», «боевой корабль», «прицел», «бомба», «мина».
Но если вы выберете другой сеттинг, вам будет проще, ну или выберете другую нейросеть;
2. Нейросеть не понимает концепт спрайта. Опустим момент, что изображения генерируются с непрозрачным фоном — это можно легко поправить (даже другими нейронками). Для игры нам нужно изобразить объекты либо сбоку, либо сверху, либо под 45 градусов для игр в изометрии, нейросеть же упрямо генерировала что‑то такое:


Единственный способ генерировать плоские арты который я нашёл — это добавлять ключевое слово «пиксельарт», но такой стиль подойдёт не всем проектам.

И раз мы заговорили о стиле перейдём к следующему пункту;
3. В начале статьи я привёл скриншот своей игры. И не мне говорить о стиле и дизайне, но у нейросетей могут быть проблемы с генерацией в определенном стиле или с соблюдением ограничений, связанных с лором игры. К примеру, в моей игре все корабли — это беспилотники, управляемые ИИ, но на изображениях упорно проступает что‑то похожее на кабину пилота или мостик, а если добавить в промпт слово «робот», то в итоге получаем что‑то гандамо‑меха‑подобное, а о том, почему не стоит добавлять в промт слово «беспилотник», см. пункт 1.
4. Также могут возникнуть сложности с генерацией картинок для кнопок, иконок и прочих частей интерфейса, ИИ очень любит перегружать изображения мелкими деталями и «красивостями», что ухудшает читаемость, и при масштабировании картинки могут выглядеть отвратительно;
5. Предубеждение общества к нейроконтенту. Когда я пишу эти строки, в памяти ещё свеж скандал с нейро‑скинами в Call of Duty. Также я однажды видел в магазине пару, которые не стали покупать новогодний набор конфет, украшенный сгенерированным изображением. У некоторых людей сейчас вырабатывается стереотип, что если обложка игры в стиме или упаковка товара в магазине нарисована при помощи ИИ, то продукт будет сомнительного качества: если уж создатели настолько сэкономили на внешнем виде, то и содержимое может быть не очень.
Перед написанием этой статьи я попробовал ещё несколько сайтов с генерацией картинок, и в целом прогресс не особо наблюдал.
С другой стороны, какой‑то процент работы всё же можно переложить на LLM: рисование фонов, доработка и небольшие изменения существующих изображений. К тому же для себя вы можете выбрать нарочито провокативный стиль и наоборот выпячивать использование нейросетей — может быть, это выстрелит;
С написанием кода дела обстояли не лучше. Знаете, я не очень люблю делать ревью чужого кода, но при работе с ИИ только и занимался тем, что досконально просматривал его код, иначе код проекта превратился бы в минное поле из багов.
Вайб‑кодинг — это как будто про создание прототипа, который будет выброшен на свалку после первой же презентации. Можете считать меня ретроградом, но мне реально проще писать код самому и понимать, что мой код делает, понимать где искать ошибку, если что‑то идёт не так, понимать, где нужно внести изменения и что‑то поправить.
До генерации музыки я не добрался, но на это я пока возлагаю большие надежды: всё же в youtube полно сгенерированных клипов. Но, возможно, и тут меня ждёт разочарование)
Как отсечь лишнее
Кто‑то (возможно, это был Кармарк) сказал: «Игра — это последовательность выборов». Эти слова идеально подходят к любой игре. Играя, мы постоянно выбираем реплику в диалоге, квест, который начнём делать прямо сейчас, награду за этот квест, амулет на +2 силы или амулет на +1 силы и +1 ловкости, шмальнуть по группе врагов из ракетомёта или приберечь ракеты для битвы с боссом.
Если вы сомневаетесь, нужно ли добавлять что‑то в игру или удалять из неё, я бы предложил спросить себя, как это повлияет на количество возможных выборов для игрока. Если изменение увеличивает пространство доступных выборов, то это нужное изменение, если сокращает, то нам такое не надо.
Например, у меня была идея разделить очки перемещения и очки атаки, примерно как в Warhammer 40,000: Rogue Trader, но так, чтобы атака не прерывала ход. Но потом пришлось отказаться от этого в пользу единых очков действия, которые можно использовать и для атаки, и для перемещения.
В первом случае (очки разделены) при столкновении с врагом тактика была бы всегда одна и та же:
Если очков перемещения достаточно, то приближаемся на дистанцию атаки;
Атакуем, пока не потратим все очки атаки;
Если после п.1 остались очки перемещения — отступаем;
Во втором случае (очки едины) у нас есть куда больший выбор тактик, поэтому обозначу только две возможные крайности. Первая:
Тратим пару очков и приближаемся;
Тратим пару очков на атаку;
Тратим все оставшиеся очки, чтобы убежать;
Вторая — тактика «ударил / отступил», но можно и наоборот:
Ждём, когда противник сам приблизится. Тогда сливаем все очки на то, чтобы максимально сократить дистанцию и завершаем ход;
Как только враг в зоне поражения, тратим все очки действия на атаку, не думая об отступлении и рассчитывая закончить схватку одним ударом;
Как видите, при использовании единых очков действия вариантов для выбора у игрока намного больше.
Правда, тут есть нюанс: если у нас есть отдельные очки движения и атаки, то можно ввести в игру корабли с разным количеством очков атаки и перемещения, а также их модификации, направленные на увеличение количества тех или других. т. е. переходом на единые очки действия я бы расширил для игрока возможность тактических выборов, но сократил количество стратегических; и поскольку выбор корабля и модификаций для него происходит реже, чем тактический выбор «бей / беги», то решение было принято в пользу единых очков.
Ещё важно избегать ситуаций, когда выбор вроде и есть, а по факту его нет. Например, вам предлагают выбрать между амулетами на +10 к урону, +15 к урону и +20 к урону. У вас есть три варианта на выбор, но очевидно, что тут по сути и выбора‑то нет: берём амулет на +20 и всё. Другое дело, если выбор будет между амулетами на +10 к урону или +20 к урону и -20 к защите, вот тут уже есть над чем задуматься, и хотя вариантов стало меньше, ценность решения игрока стала больше, а последствия у такого выбора будут различаться сильнее.
Резюмируя: чем больше в игре ситуаций, когда игрок должен сделать выбор или принять решение, и чем чаще игрок сталкивается с последствиями своего выбора, тем лучше.
Процедурная генерация оружия
Зацените первоначальный концепт моей игры. Три фракции сражаются за территорию. При захвате территорий корабли каждой фракции, их оснащение и вооружение генерируются процедурно в зависимости от того, какие именно сектора карты территории контролирует фракция.
Звучит круто, жаль, что после это всё не работает…
Схема была простая — у нас есть набор предметов с базовыми характеристиками (пушка, ракетомёт, реактор, ремкоплект и т.д), есть набор модификаторов, каждый из которых увеличивает или уменьшает определенные характеристики. Например, при генерации новой пушки случайно выбираем количество модификаторов и применяем их, и вот из скучной пушки с дальностью 1 и уроном 10 у нас получается крутая и стильная «Дальнобойная с повышенным уроном скорострельная пушка» с дальностью 3, уроном 18 и пониженным временем перезарядки. Круто же! А если вы реально дёргали модификаторы рандомно и не следили за их уникальностью, то может быть «Скорострельная дальнобойная скорострельная скорострельная пушка». И даже в таком случае разработчику всё ещё не нужно сидеть и прописывать 20 разных видов пушек вручную.

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

Нет, не круто. У такого подхода есть один недостаток — отсутствие читаемости. В игре при взгляде на противника вы должны начать догадываться, чего от него ждать.
Вот вам пример из классики:

На картинке классическая игра. Сможете угадать, у какого танка самая прочная броня?
Игроку нужно дать возможность понимать, чего ждать от того или иного противника, дать возможность изучить повадки конкретного врага и выработать против него тактику, но с процедурной генерацией врагов на лету я этот момент заруинил. Для себя из этой ситуации я вынес несколько выводов:
Можно процедурно генерировать карты, я например использовал вот эту статью для расстановки астероидов https://habr.com/ru/articles/653 515/;
При желании добавить в игру сгенерированное оружие и не давать его рядовым противникам: пусть обычный враг всегда стреляет из дефолтной пушки, но при его смерти с него может падать сгенерированная пушка;
Можно также выдать боссам процедурно сгенерированное оружие или даже процедурно создавать самих боссов. Правда, тут кроется риск создать непобедимого ублюдка;
Можно при старте каждого нового прохождения игроком или на старте забега немножко менять параметры противников, чтобы разные прохождения немного отличались друг от друга;
Вроде бы это всё очевидные вещи, но почему‑то я всё это осознал уже на этапе тестирования.
Билды
Ох, что‑то я выдыхаюсь, похоже писать тексты это немного не моё…
Но напоследок давайте расскажу про ещё одну вещь. Вообще на ютубе есть отличное видео по основам билдостроения. Гуглите «Как делать крутое билдостроение в играх? Синергии, эмерджентность, ограничения» на канале «ТотСамыйКелин».
Я проговорю основные моменты как понял сам. Хорошая билдостроительная система стоит на трёх китах:
Ограничения — нельзя позволить игроку использовать всё что есть в игре. В том же Doom игрок может таскать на себе весь арсенал, а вот в Crysis можно носить только две пушки — это уже зачаток билдостроения;
Синергии — это когда разные части билда влияют друг на друга. Сюда можно разные бонусы, которые складываются с неким коэффициентом (сапоги +20 к скорости и шлем +10 к скорости при одновременном ношении дадут +32 к скорости, +2 за использование однотипного баффа), а также усиление одних вещей другими (шлем, увеличивающий урон из снайперских винтовок или броня, увеличивающая урон дробовиком);
Эмерджентность — когда сочетание определённых вещей позволяет делать то, что недоступно при использовании любой из этих вещей по отдельности. Например, у вас есть предмет, вызывающий взрыв при получении вами урона, предмет, ускоряющий перезарядку других предметов и предмет, лечащий вас, когда вы нанесли урон нескольким противникам одновременно. По отдельности все три предмета не сильно меняют геймплей, но все вместе они позволят вам использовать тактику, когда вы врываетесь в толпу врагов, получаете удар, происходит взрыв, враги получают урон, а вы тут же исцеляетесь.
При создании игры я ориентировался на эти пункты. Сперва я думал, что можно просто создавать для игры разные предметы и случайно наделять их синергией друг с другом, а игроки уже сами потом придумают билды. Но потом меня озарило, что нужно идти от обратного: придумываем несколько основных билдов, которые могут собрать игроки (варвар, амазонка, паладин, маг, некромант), а потом, уже отталкиваясь от списка билдов, придумываем предметы, которые будут добавлены в игру. Так будет проще придумывать нужное снаряжение и бонусы и отметать ненужное.
Заключение
Спасибо, что прочитали мою первую статью. Надеюсь, она кому‑нибудь поможет сделать свою игру! Ну, а я пойду пытаться сделать новый проект, это будет экстракшен‑лутер‑шутер про роботов на UE :‑)