Cоветы по работе в GameMaker на примере психологического триллера

Привет!

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

Оговорюсь, по образованию я не программист, а врач, но разрабатываю игры в 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(audiogroup_name)) {room_goto_next();} else {audio_group_load(audiogroup_name);}

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

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

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

Лоретта тащит мужа.
Лоретта тащит мужа.

К примеру, моя последняя игра 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 не поставляется с какими-либо кодеками и использует кодеки, присутствующие на платформе, на которой работает игра. Это означает, что ваши видео должны быть закодированы в формате, который можно декодировать на предполагаемых целевых платформах.”

Официальное руководство GameMaker

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

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

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

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

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

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

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

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

Вот сюда нужно залить файлы из официального расширения.
Вот сюда нужно залить файлы из официального расширения.

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

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

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

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

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

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

  • Конечно, очень глупая, но такая легкая для свершения ошибка. Причем до поры до времени, если у вас более-менее нормальный компьютер, можно и не заметить. Проверять, что объекты не создаются бесконечное количество раз. Например, так: if !instance_exists(obj_name) {instance_create_layer(x,y, “name_layer”, obj_name)}
  • Пользоваться горячими клавишами. Полезны нажатие Alt — выделение столбика. И Ctrl+Shift+F — открытие поиска по проекту. Пользоваться middle-click на мышке для быстрого перехода к функции, объекту или скрипту.
  • Проверять синтаксические ошибки. И стараться убирать. Потому что проект компилируется и даже может работать, но никто не в силах предсказать, к чему в итоге приведёт.
  • Больше заниматься спортом и меньше пить:(

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

И спасибо!

125125
27 комментариев

Не пей, не грусти, спасибо за пост

7

Не грущу, вам спасибо, что читаете:3

4

Приятно видеть полезную статью про Game Maker на dtf. Так держать!

6

Выглядит отлично. Успеха в будущем релизе!

5

хуй знает о чем статья, но игру ты мне продал

4

Спасибо) Недавно начал познавать этот движок и у меня тут вопрос появился, на который я не смог найти ответа в гугле. Может вы поможете.

Собсно вопро: Можно ли каким то образов выставить порядок запуска объектов?
Попытаюсь объяснить: Допустим, у меня есть отдельный "пустышка" объект, отвечающий за отрисовку всего gui в игре и все бы ничего, но он с какого-то хрена решил, что его события непременно должны запускаться самыми первыми в игре. В итоге, так как объект отрисовывает gui, он часто обращается к переменным из других объектов, которых может или ещё не существовать, или они могут быть уже удалены и не созданы заново.

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

2

Смотри Creation Order (или типа того) в Room Editor.

3