Матчасть
December 4, 2022

Описываем игровую логику. «Процедурные» схемы

Появилась идея сделать серию статей о том, как правильно описывать логику и формировать будущую модель игры. Я думаю, что заметки на эту тему могут быть полезны не только начинающим, но и опытным геймдизайнерам.

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

Ссылки на статьи буду выкладывать в телеграмм-канал: https://t.me/SecretRoom_Gamedesign

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

Например, нам нужно описать что-то из следующего:

  • Логика работы ивента
  • Логика вызова попапов и переходов между окнами
  • Система диалогов

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

Обычно такая логика описывается блок-схемами.

Давайте рассмотрим ошибки, которые могут совершаться при составлении таких схем.

Ошибка 1: Схема начинается с условия, а не с действия

Рассмотрим такую схему:

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

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

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

Что дает геймдизайнеру исключение такой ошибки на этапе формирования схем?

Давайте начнем исправлять схему:

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

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

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

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

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

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

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

Событие как начало схемы

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

Рассмотрим пример. Нам нужно описать флоу, которое происходит каждый раз, когда мы запускаем попап со списком задач в Homescapes. Если у нас есть выполненные задачи в планшете, то при открытии попапа запускается череда анимаций: Установка галочки, убирание задачи из списка, начисление прогресса и т. д.

Мы можем отталкиваться от события «Попап открылся», потому что мы понимаем, что попап не может открыться сам по себе. Причиной открытия попапа всегда является некое действие игрока. Например, игрок нажал на кнопку в главном меню или же попап был вызван из другого флоу, которое уже было проинициировано действием пользователя.

Ошибка 2: Слишком «связанная» схема

Продолжаем наш пример с ивентом «Рабочие будни».

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

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

Изобразим это в виде схемы:

Найдем здесь ошибку: по схеме получается, что если игрок зайдет на попап ивента до накопления прогресса, необходимого для приза, он не увидит анимации заполнения полоски прогресса. Грустно.

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

Теперь не важно, каким способом мы попали внутрь попапа ивента. Мы всегда сможем увидеть анимацию прогресса.

Давайте разобьем схему еще больше, при этом сохранив логику (дальше мы поймем для чего это будет нужно):

Процедуры

Я бы назвал этот способ составления схем «процедурным», потому что мы разбиваем логику игры на «процедуры» — некие неделимые последовательности действий, которые начинаются либо с команды игрока, либо вызываются из других процедур.

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

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

Кстати, такие приоритеты будет очень удобно хранить в виде таблицы

Процедурный способ не всегда подходит для описания логики игры. Реакции игры могут быть асинхронными и не всегда зависеть напрямую от действий игрока. Игра может выдавать некие сообщения или изменять свое состояние без явной команды от игрока. Например, «процедурами» трудно будет описать кор-геймплей какой-нибудь игры в реальном времени, например, PVP-шутера.

Для этой цели могут помочь конечные автоматы. О них я расскажу уже в следующий раз.

Чтобы не пропустить пост, не забудьте подписаться: https://t.me/SecretRoom_Gamedesign