Привет!

Меня зовут Яков. Последние годы я придумываю и разрабатываю инди-игры практически в одиночестве.

Оговорюсь, по образованию я не программист, а врач, но разрабатываю игры в Game Maker с 2016 года, что стало сегодня моей основной работой. И мне пришлось создать три игры прежде, чем понять эти простые, но важные, как мне кажется, принципы. 

Скриншот из моей последней игры - Loretta. О женщине, которая убила мужа в 1947 году.
Скриншот из моей последней игры - Loretta. О женщине, которая убила мужа в 1947 году.

GameMaker удивителен тем, как одну и туже проблему можно решить совершенно по-разному. Потому я не претендую на истину, кроме того не думаю, что советы справедливы для любой игры, но буду рад открыть дискуссию, кому-то помочь, да и узнать, если я в чем-нибудь заблуждаюсь. Вот, что я выяснил:

Не стоит использовать game_restart();

Функция, как понятно, перезагружает игру. Но не совсем. Теоретически, она существует больше для тестов. Не рекомендую использовать ее вообще. Вместо нее для игры я переписал кастомный скрипт с использованием #macro, основываясь на этой статье

Которая в свою очередь ссылается на еще более детальный обзор.

#macro game_restart __game_restart

function __game_restart() {
  
  with(all) 
  {
	instance_destroy();	
  }

audio_stop_all();
draw_texture_flush();

draw_set_halign(fa_left);
draw_set_valign(fa_top);
draw_set_font(-1);

room_goto(room_first)

}

В сущности, скрипт удаляет все объекты, выключает звуки и музыку, и возвращает игрока в первую комнату, в меню, ну, или куда угодно, не создавая при этом непредвиденных багов.

Не стоит включать галочку в Persistent в редакторах комнат;

Галочка Persistent выключена по умолчанию в каждой новой комнате. Пусть такой и остается.
Галочка Persistent выключена по умолчанию в каждой новой комнате. Пусть такой и остается.

В Loretta сюжет разбит на главы. Так, в начальном экране любой главы у меня есть объект obj_ini_chapter, в котором я объявляю все глобальные переменные.

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

Необходимо разбивать ресурсы на аудио- и текстурные группы;

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

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

Со звуком в Game Maker проблема, похоже, была всегда. Лично я пользуюсь официальным руководством по оптимизации.

Все звуки конвертирую в .ogg. А большие звуковые файлы стримлю прямо из папки с игрой, что, разумеется, подходит вам только в том случае, если вы не собираетесь продавать саундтрек отдельно.

Таким образом, я объявляю все звуки для новой главы в начальной, ну или той комнате, где происходит сохранение, и вызываю аудио-группу с помощью:

audio_group_load(audiogroup_name);

А чтобы убедиться, что все звуки загрузились, я вставляю в начальной загрузочной комнате каждой главы:

if (audio_group_is_loaded(audioExpo))
{room_goto_next();} else {audio_group_load(audioExpo);}

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

Выборы и последствия

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

Пример выбора в диалогах
Пример выбора в диалогах

К примеру, моя последняя игра Loretta — психологический триллер, разворачивающийся в Америке в 1947 году. История о униженной и обманутой домохозяйке в несчастном браке и с непростой судьбой, которая решается на убийство мужа. Развитие истории зависит от игрока: сюжет может превратиться как в череду кровавых убийств, так и в паутину изворотливой лжи. 

Можно убить этого неприятного толстяка
Можно убить этого неприятного толстяка

Поэтому я с самого начала решил, что в игре можно убить любого важного персонажа. И разумеется, расплатиться за это. Мне этого не хватало в квестах. Вспоминаю разве что Harvester 1996 года. При этом убийство или попытка убийства имеет либо сиюминутное последствие, либо влияет на события ближе к концу игры.

Я реализовал это через создание ini-файлов.

if (file_exists("Murder.sav")) file_delete("Murder.sav");
  ini_open("Murder.sav")
	ini_write_real("murder","dead", 1);
	ini_close();

А затем игра просто проверяет, существует ли тот или иной файл, и меняет диалоги, ситуации, предметы и так далее.

Сюжетные главы я разбил на воспоминания героини, вход в которые предвосхищают небольшие, абстрактные, но связанные с сюжетом, пазлы.  Сами по себе механики простые. Почти по-детски. Но я руководствовался тем, что игрок должен достаточно быстро их решать. А вдохновился, банально, The Caretaker - Everywhere At The End Of Time.

Обращая, таким образом, простой jigsaw-пазл в сюжетно-эстетический компонент игры. Ну и конечно, все головоломки-воспоминания немного разные, чтобы не надоесть.

При этом, если игрок вдруг захочет пройти главу вновь, то головоломка автоматически пропустится, благодаря все тем же ini-файлам.

Очень вероятно, что есть более умные и элегантные методы, но повторюсь, этот метод тоже работает и не подводит.

Локализация

У меня есть одна большая табличка в гугл-доке, где содержится весь текст игры.

Вот, как примерно выглядит таблица
Вот, как примерно выглядит таблица

А каждый столбик содержит в себе тот или иной язык. Помимо английского и русского, я перевожу свою игру на японский и китайский. И если с латиницей и кириллицей все довольно просто, то с языками, входящими в CJK, не совсем. В общем говоря, вам нужен шрифт. 

Шрифт не просто должен быть в открытом доступе, но и иметь лицензию, при которой разрешено распространять его папке со своим приложением. Я использую BabelStoneHan.

Похожая ситуация с видео. Совсем недавно добавили или вернули функцию проигрывания видео.

При этом в официальном руководстве сказано, что:

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

Разобраться в юридических нюансах кодеков, психически здоровому человеку, мне кажется, невозможно. Все снимают с себя ответственность.

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

Как только Opera выкупила GameMaker, все стало меняться. Медленно, топорно, но в лучшую сторону. Почти каждый месяц выходят обновления.

Opera продвигает свой браузер для геймеров. Я даже скомпилировал демку Loretta для одного из конкурсов, где игра выиграла в направлении арт-дирекшен. Так что жаловаться не имею права. Но велика вероятность, что с каждым обновлением что-то в проекте может сломаться, перестать работать.

Игра и правда получилась красивой:3
Игра и правда получилась красивой:3

Внедрение Steam API в игру на GameMaker;

С последним обновлением поменялось и внедрение API. Пока я протестировал это лишь для Steam. Но полагаю, что для остальных платформ процесс теперь будет похожим. Есть бесплатное, официальное расширение, которое нужно скачать и воспользоваться инструкцией.

Но очень часто люди ошибаются и добавляют файлы из расширения в “Included file”, где хранится, к примеру, шрифт, видео, текстовый файл с переводом. А этого делать нельзя. Файлы из расширения необходимо закинуть в папку с самим .yyp-проектом.

Как можно раньше добавить поддержку контроллера;

Какую бы игру вы сегодня не разрабатывали или не планируете разрабатывать, лучше сразу прикручивать управление контроллером. Подсказки для них. И планировать даже геймплей, исходя из этого.

Подсказки для XBOX-геймпада
Подсказки для XBOX-геймпада

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

Подсказки для PS-геймпада
Подсказки для PS-геймпада

И еще совсем маленькие, возможно, даже немного дурацкие, но, как мне кажется, важные советы:

  • Конечно, очень глупая, но такая легкая для совершения ошибка. Причем до поры до времени, если у вас более-менее нормальный компьютер, можно и не заметить. В общем, проверять, что объекты не создается бесконечное количество раз.

  • Пользоваться горячими клавишами. Полезны нажатие Alt —выделение столбика. И Ctrl+Shift+F — открытие поиска по проекту. Пользоваться middle-click на мышке для быстрого перехода к функции, объекту или скрипту.

  • Проверять синтаксические ошибки. И стараться убирать. Потому что проект компилируется и даже может работать, но никто не в силах предсказать, к чему в итоге приведёт.

Сейчас я готовлю новую демку Loretta для грядущего фестиваля игр в Steam. И приглашаю вас сыграть, и если понравится, купить за честно заработанные тенге, ну а пока просто добавить в вишлист.

И спасибо!

Комментарии (3)


  1. alnite
    02.06.2022 21:09

    Жаль, не могу поставить плюсик, но очень толковая статья получилась; кратко, но по делу, и интересно даже для постороннего :)

    Какой-то коммерческий "выхлоп" удолось получить по прошествии времени?


    1. 2PAE
      03.06.2022 07:42

      Человек пишет что это его работа теперь. Создавать игры. Значит на жизнь хватает.


    1. butuzoff_ya Автор
      03.06.2022 08:58

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