Книга: Создаем игры с нуля! 3 книги для старта в гейм-деве
Назад: Глава 10 Как это сделано
Дальше: Глава 12 Проблема выбора

Глава 11
Переменные. Программистская логика в структуре сюжета

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

 

 

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

Что такое переменные?

Термин «переменная» – это перевод английского слова variable, в этом значении он активно используется в программировании. Если говорить формальным языком, то это понятие обозначает поименованную или адресуемую иным способом область памяти, которую можно использовать для доступа к данным.
Переменная – это хранилище данных с каким-то значением, которое впоследствии может использоваться в программе.
Вначале мы, конечно, должны обозначить переменную, придумать ей имя – задать, то есть сделать ей своеобразную «упаковку» – инструкцию (instruction). Для этого применяются разные языки программирования, и переменные назначаются в зависимости от синтаксиса. Обычно переменные задаются английскими словами на латинице – для распознавания кода большинством программ. Пробелы не используем, они вообще являются страшным проклятьем в коде, так как не сразу заметны, надо быть внимательнее и обязательно удалять их. Вместо пробелов можно использовать нижнее подчеркивание или воспользоваться системой CamelCase (с англ. «ВерблюжийРегистр», также «ГорбатыйРегистр»), где каждое выделенное слово в переменной начинается с большой буквы. К примеру, RedMagicHat. Программисты вам скажут спасибо!
Что же это за «упаковка» такая? Давайте попробуем визуализировать ее на примере.
Представим себе, что находимся в гостях у Деда Мороза, а именно в его мастерской, где в мешочках и коробочках находятся подарки, – пусть это и будут наши хранилища данных с переменными. Каждый подарок на учете у Деда Мороза и упакован – имеет инструкцию. Он запечатан до той поры, пока не будет вручен ребенку и открыт, то есть пока данная переменная не будет использована.
При этом, если представить переменную в виде подарочной коробочки, например назовем ее box, то внутрь мы можем положить какую угодно игрушку для ребенка – doll.
И мы можем менять игрушку столько раз, сколько потребуется.
box = 'doll!';
box = 'bear!';
И так далее. Все зависит от концепции использования переменных в нашем проекте.

 

Типы переменных и их логика

Переменные мы будем рассматривать в рамках визуального программирования, то есть метода работы с графическими объектами, без написания строчек кода, с так называемыми нодами. Это несложный способ понять, как работать с переменными без знания языка программирования. Мы коснемся лишь той части знаний, которая нужна для логики построения интерактивных историй.
Переменные по зоне видимости
Глобальные (Global) – переменные, которые доступны всей программе во всем проекте.
Локальные (Local) – переменные, которые доступны конкретной подпрограмме.
Мы остановимся лишь на первом варианте – на глобальных переменных, именно они актуальны для наших целей.
Переменные по функциональности
У каждой переменной есть своя функция и способ объявления, это как раз наша пресловутая «упаковка», о которой мы говорили чуть выше. Итак, мы рассмотрим три вида переменных.
● Логические булевы (Boolean)
● Строковые (String)
● Целочисленные (Integer)
Логическая булева переменная (Boolean Variable)
Это переменная, которая несет в себе информацию о том, истинно или ложно то или иное свершение, событие, утверждение, данные. Мы оперируем понятиями правда (true) или ложь (false). Исходя из этой довольно простой программной логики, можно создавать весьма ветвистое сюжетное древо.

 

Пример
Давайте рассмотрим логическую (булеву) переменную на примере.
Дед Мороз положил в один подарочный мешочек плюшевого мишку, а в другой – куклу. Какой подарок получит Мария, мы можем запомнить и использовать дальше в истории.
Мы вводим переменную Bear и фиксируем данную информацию таким образом:
● true (да, правда) – это наличие медведя.
● false (нет, ложь) – это отсутствие медведя.
Соответственно, в тех моментах истории, где важна подаренная Дедом Морозом игрушка, мы пользуемся логикой переменной Bear, проверяя, есть ли у Марии медведь.

 

Целочисленная переменная (Integer Variable)
Это переменная, которая несет в себе информацию о том, сколько прибавляется к той или иной игровой сущности (или убавляется от нее). Мы оперируем числовыми понятиями, обычно используемыми для прокачки отношений, инвентаря, коллекций.
Давайте рассмотрим целочисленную переменную на примере.
У Деда Мороза был продуктивный рабочий день, он упаковал 10 подарков: либо плюшевых медведей, либо кукол.
Мы вводим глобальную переменную Gifts и переменные внутри нее – Bear и Doll.
Соответственно, далее сюжет зависит от того, что же в подарках и в каком количестве.

 

 

Строковая переменная (String Variable)
Это переменная, которая несет в себе данные о ключевом слове или нескольких, строке, последовательности символов. Она используется для ввода и вывода информации, для имен, псевдонимов персонажей и кличек питомцев, указывает названия локаций, предметов и других игровых сущностей.
Давайте рассмотрим строковую переменную на примере.
Мария получила от Деда Мороза в подарок мишку. Игрок может дать ему имя или оставить то, что предлагается по дефолту.
Для этого вводим строковую переменную Name. Далее мишка будет иметь то имя, которое ему задано.

 

Набор переменных (Variable Set)

В глобальных переменных можно выбрать набор переменных (Variable Set), отвечающих за какой-то общий параметр нашего проекта. Например, это могут быть Диалоги (Dialogues), куда мы вносим переменные по запоминанию ответов на диалоги на протяжении истории и, соответственно, выбор сюжетной ветки в зависимости от них. Или Инвентарь (Inventory), когда нам нужно ввести тот или иной предмет в процессе игры.
В набор переменных мы можем вносить разные по функциональности переменные, объединенные общим признаком. Это могут быть и логические, и целочисленные, и строковые переменные. Например, если мы имеем дело с Инвентарем (Inventory), то можем столкнуться с тем, что на каком-то этапе повествования сумеем открыть в данной локации инвентарь или нет (логическая переменная: true или false), далее получить в него некое количество предметов (целочисленная переменная: +1 или +10), а также получить в инвентарь особый магический предмет, у которого есть имя (строковая переменная: «Меч Эскалибур»).

Условие (Condition)

Говоря о переменных, мы непременно сталкиваемся с условиями их использования и проверкой, исходя из которых и происходит ветвление сюжета. Обычно условиями мы проверяем логические и целочисленные переменные в ключевых сюжетных узлах, диалогах, особенных сценах, развилках пути и других элементах геймплейного повествования.
Условие (Condition) с логической булевой переменной
Условием с логической переменной мы проверяем наличие или отсутствие того или иного произошедшего события и игровой сущности.
Давайте рассмотрим на примере.
Итак, Мария получила в подарок от Деда Мороза либо мишку, либо куклу. И вот настал момент, когда нам нужно проверить это событие. Для этого мы делаем условие (condition) с уже знакомыми установками по переменной Bear:
● true (да, правда) – это наличие медведя;
● false (нет, ложь) – это отсутствие медведя (наличие куклы).
В зависимости от того, какой был сделан и запомнен выбор, развиваются сюжетные события через проверку условий.

 

Условие (Condition) с целочисленной переменной
Условие с целочисленной переменной проверяется через обычные математические равенства.
Давайте рассмотрим на примере.
Деду Морозу нужно проверить, упаковал ли вчера он 10 мишек. Для этого мы делаем проверку через глобальную переменную Gifts и переменные внутри нее Bear.

 

 

Мы также можем пользоваться знаками больше (>) или меньше (<), а также равно (=).
Например, Деду Морозу важно понять, упаковал он вчера больше 5 мишек или нет.

 

Использование переменных в интерактивных историях

Применение переменных может быть абсолютно разным – все зависит от целей проекта. Приведем примеры лишь некоторых из них.
● Отношения персонажей
● Выборы
● Статы
● Инвентарь
● Имена
Отношения персонажей
С помощью целочисленных переменных мы можем в течение истории прибавлять и убавлять единицы в отношениях с теми или иными персонажами, а в ключевых моментах делать проверки (condition). Например, если отношения с персонажем А были положительные и накоплено больше какого-либо числа, то А поможет главному герою в финальной битве с жутким драконом, что значительно увеличит шансы на победу. Если меньше, то придется справляться самому или искать другие пути.
Выборы
С помощью логических переменных мы можем делать запоминание ответов в диалогах. В зависимости от выбора ответов игрока в беседе персонажей будет зависеть дальнейшее развитие сюжета и разветвляться повествование. Например, главный герой из двух напитков – чай или кофе – выбрал кофе, и в следующем эпизоде его потчуют именно им, что повышает в истории агентивность.
Статы
С помощью целочисленных переменных игрок может прокачивать определенный стат, от чего будет зависеть, как он себя поведет в ключевых сюжетных развилках. Например, будет ли это развитие характеристик воина, мага или купца.
Инвентарь
Переменная Inventory довольно часто применяется в играх. Она может быть целочисленной или логической. В первом варианте: когда у нас прокачивается, например, оружие или волшебный артефакт. Во втором варианте: когда у нас есть возможность открыть, взять и использовать предмет при определенных обстоятельствах.
Имена
Строковые переменные дают возможность давать имена, а также указывать конкретные названия на локациях, предметах, игровых сущностях, направлять фокус внимания игрока. Например, мы можем задавать на локации определенные точки, куда будет направляться камера: Camera.Forest (фокусировка на лес), Camera.Swamp (фокусировка на болото) и т. п.

Использование переменных на примере работы в articy: draft 3

Давайте разберемся, как работают переменные в движке articy: draft 3 на практике.
Введем пять наборов переменных.
● Dialogue – чтобы запоминать, какие выборы совершены в беседах персонажей и что из этого вышло.
● Name – чтобы задать имя нашему главному герою.
● Stat – чтобы развивать ту или иную характеристику главного героя.
● Like – чтобы определиться с отношениями главного героя и других персонажей.
● Music – чтобы назначать музыку на проекте.

 

Задаем на старте переменные на примере программы articy: draft 3
В articy: draft 3 все переменные назначаются в разделе Global Variables.

 

 

Нажимаем на катушку и вводим указанные наборы переменных.

 

 

Вводим имя.

 

 

Делаем остальные сеты переменных, нажав на катушку и введя имя: Dialogue, Like, Name, Music, Stat.
Теперь в каждом из сетов переменных встраиваем собственные целочисленные, строковые и логические переменные, которые подходят именно вашему проекту.
Для этого мы в каждом из сетов нажимаем крестик, чтобы создать переменную внутри него.

 

 

В Dialogue мы можем называть наши переменные в зависимости от ситуации, когда происходит выбор. Например, в разговоре с магом мы выбираем, что больше привлекает главного героя: оружие или книги. Для этого вводим логическую булеву переменную Dialogue.Books_1, где 1 – это номер сцены, где впервые появляется данный выбор. Переменных может быть столько, сколько угодно. Обращаем внимание, что в Type у нас стоит Boolean и в Default Value – false.
Обычно здесь булевы переменные (true/false).

 

 

В Like мы закладываем отношения, которые главный герой может развивать с другими персонажами: любовь, дружба, симпатия. Мы можем помечать именами нужных для повествования персонажей внутри сета переменных. Например, Mary. В Type мы выставляем Integer, в Default Value оставляем 0. В дальнейшем можно прибавлять и убавлять количество единиц в зависимости от тех выборов, которые совершает игрок.

 

 

В Music мы обычно назначаем тип музыки, который будет раздаваться в тех или иных событиях игры. Например, атака – Attack, главная тема – MainTheme, приключения – Adventure и т. д. Все зависит от целей и атмосферы игры.
Обычно здесь булевы переменные (true/false). Обращаем внимание, что в Type у нас стоит Boolean и в Default Value – false.

 

 

В Stat мы можем назначить несколько характеристик/путей, по которым будет развиваться главный герой. Это может быть, например, воин или маг.
Обычно это целочисленная переменная. В Type мы выставляем Integer, в Default Value оставляем 0. В дальнейшем можем прибавлять и убавлять количество единиц в зависимости от тех выборов, которые совершает игрок.

 

 

 

В Name мы применяем строковые переменные. Например, решим, чтобы игрок сам выбрал имя главного героя. Введем переменную Hero, в Type выбираем String, в Default Value вписываем имя, которое у нас будет применяться по дефолту. Например, Albert.

 

 

Можем экспериментировать и с именами других персонажей. Например, у нас есть персонаж Мария. При первом появлении мы задаем ей имя «Красотка», так как еще не знаем, как ее зовут.

 

Использование переменных в проекте
Итак, мы сделали предварительную работу – задали переменные в начале проекта. Как же они интегрируются на протяжении всей истории?
В самом проекте мы используем переменные как инструкции (Instruction), выбирая их и вставляя каждую из введенных переменных в повествование в задуманных местах.

 

Name
Вводим переменную Name.Hero = „“;

 

 

Далее в тексте главного героя следует называть установленным набором символов, например hname (hero name). Это связано с тем, что игрок может назвать своего героя как угодно или оставить дефолтное имя.
Важное правило: с именем игрока hname используется только именительный падеж и единственное число, ни в коем случае не косвенные падежи – во избежание грамматических ошибок.
Мы можем вводить имена других персонажей по мере их выяснения, вписав в кавычки.
Вводим переменную Name.Mary = „Мария“;

 

 

Music
Необходимую музыку на том или ином отрезке повествования мы «включаем» – true и «выключаем» – false.

 

 

Dialogue
Вводим переменную Dialogue.Books_1

 

 

Like
Вводим переменную Like.Mary = +2;

 

 

Stat
Вводим переменные Stat.Warrior = +2; и Stat.Mag = +2;

 

Условия (Conditions) переменных в проекте

Условия нужны в основном для логических и целочисленных переменных. Не забываем про синтаксис – пишем двойное равенство.

 

Dialogue
Вводим условие по переменной Dialogue.Books_1 == true;

 

 

Like
Вводим условие Like.Mary >= 5;

 

 

Stat
Вводим условие Stat.Mag > Stat.Warrior;

 

 

Таким образом, обладая базовыми знаниями о переменных, мы можем делать истории с невероятно разветвленными деревьями сюжета, выстраивать уникальные пути прохождения игрока. При этом не нужно постоянно контролировать, все ли верно встроено в повествование, за нас это делает специально обученная программа. Главное – грамотно настроить все в начале работы.
Назад: Глава 10 Как это сделано
Дальше: Глава 12 Проблема выбора