Идея использовать электронные таблицы в качестве среды для разработки игрушек не нова. В этой статье я поделюсь опытом в создании движков для ролевых игр живого действия и тимбилдингов, которые смогут сильно облегчить жизнь игропрактикам.
Зачем это надо
Допустим, вы проводите игру, в которой участвует одновременно 50-60 человек. У каждого игрока есть набор личных параметров (например, опыт, деньги, здоровье, репутация), которые меняются в зависимости от совершенных им действий. Также есть ряд общеигровых показателей (например, экология, бюджет страны или рейтинг правительства), которые также колеблются в соответствии с действиями и решениями игроков. А еще есть игровые события, которые происходят при определенной комбинации внешних факторов.
В общем, это довольно плотный поток информации, который нуждается в оперативном и точном просчитывании. В классической ролевой игре эту функцию обычно выполняют мастера игры. Но мастер не застрахован от ошибок, и много информации он все равно не обработает — ни в голове, ни даже при помощи листка бумаги.
С электронным движком один человек способен обрабатывать информационный поток любого объема. При этом игровую статистику можно выводить на проектор, чтобы участники в реальном времени наблюдали, как их действия влияют на игровые расклады. Или, например, можно показывать секретные данные каждому игроку адресно на смартфон. И самое главное — пользоваться таким движком можно совершенно бесплатно!
Увлекшись игровыми практиками около года назад, я успел написать 7 движков для разных командообразующих игр. Большая часть из этих игр имеет коммерческий успех, а одна даже продалась в качестве франшизы за границу.
Денежный поток
Все началось с игры «Денежный поток». Знакомые пригласили меня поиграть в знаменитую настолку Роберта Кийосаки, и она меня очень зацепила. Единственное, что раздражало в игре, — это необходимость постоянно производить расчеты в столбик, стирать ластиком устаревшие данные и вносить новые. Из-за того, что все участники, боясь ошибиться, были постоянно сконцентрированы на собственных расчетах, игра сильно теряла в динамике и затягивалась на долгие часы.
Я решил оптимизировать игровой процесс, переведя все калькуляции в Гугл-таблицу.
Чтобы протестировать этот «калькулятор», я провел несколько игр для друзей. Эффект был потрясающий! Вместо того, чтобы корпеть над вычислениями, игроки активно вовлекались в игровой процесс, вели переговоры, придумывали сложные финансовые схемы и махинации. Скорость самой игры возросла почти в два раза. Нам впервые удалось довести ее до конца, когда все игроки покинули дорожку крысиных бегов и достигли своих целей. Для сравнения, в «ручной» версии участникам едва хватало терпения доиграть до того момента, когда хотя бы кому-то одному удавалось выйти на большой круг.
«Офигеть! — воскликнул мой товарищ Рубен во время одной из игр. — Восемь взрослых мужиков собрались, чтобы весь вечер пялиться на экран с гугл-табличкой. Но это реально интереснее любого кино!»
Мою табличку для расчетов в игре «Денежный поток» можно скачать отсюда. Если не до конца будет понятно, как ей пользоваться, напишите мне, и я вышлю подробную инструкцию.
Зомби, президенты и ассасины
Немного позже я наткнулся на сценарий кабинетной ролевой игры «All The President's Zombies» американского геймдизайнера Майка Янга. По сюжету, в стране происходит зомби-апокалипсис, и группа высших чиновников собирается в кабинете президента, чтобы выработать план по решению этой проблемы.
Концепция мне понравилась, и я решил создать свою собственную игру, локализовав творение Янга. Получилась игра «Экстренное совещание», которая достаточно далеко ушла от оригинала. В ее основе — развесистое дерево событий, которые в реальном времени происходят в зависимости от тех или иных решений, принятых игроками на совещании. Вместо того, чтобы кропотливо обучать мастеров игры, я создал гугл-таблицу, которая автоматически вычисляла последствия каждого из предпринятых игроками действий. Ведущему оставалось только ставить на экране галочки и вытягивать из колоды карты, номера которых высвечивались в таблице.
Определенную сложность у меня вызвала необходимость отслеживать динамику игровых параметров. Ведь при изменении значения ячейки таблица моментально пересчитывает все связанные с ней формулы, нигде не сохраняя старого значения. Я придумал, как обойти эту сложность, но об этом расскажу ниже.
Проведя пару десятков «Экстренных совещаний» для друзей и знакомых, я понял, что это перспективный формат для всякого рода тимбилдингов и корпоративных историй. Мешало только ограничение на максимальное число участников в 12 человек. И я стал придумывать новые игры, в которые можно было бы играть большим коллективом. При этом управлять игровой экосистемой должен был по-прежнему один ведущий. Так появились игры «Чумовая Венеция» по мотивам франшизы Assassin’s Creed, «Мировое господство» о противостоянии сверхдержав на мировой арене, «День выборов» о честных и не очень политических технологиях и еще несколько игр, решающих специфические задачи конкретных заказчиков.
При разработке каждой из этих игр я сталкивался с определенными сложностями, и сейчас разберу несколько наиболее интересных примеров.
Проблема — решение
В основе любого игрового движка лежит следующая последовательность действий: 1) сбор информации о решениях, принятых игроками, 2) ввод этой информации в систему, 3) проверка условий и вычисление системой новых данных, 4) выдача игрокам новых данных. В зависимости от сюжета игры, этот цикл может повторяться от одного до условно бесконечного числа раз. При этом вся коммуникация игроков, предшествующая принятию окончательных решений, остается «за кадром», и игровой системой никак не учитывается. Так что в целом процесс не производит ощущения компьютерной игры, оставляя простор для живого эмоционального взаимодействия.
Эмуляция циклов
Основная сложность при разработке движка в гугл-таблице — отсутствие таких привычных программисту сущностей, как переменная, цикл, прерывание, процедура.
Допустим, отсутствующие кнопки можно заменить ячейкой со значением «чекбокс» — в какой-то отдельной ячейке тогда будет формула, проверяющая состояние чекбокса и вычисляющая в зависимости от этого значение целевой ячейки. Но как быть с тем фактом, что вся таблица статична во времени, и при изменении значения одной ячейки-переменной моментально и «без спроса» пересчитываются значения всех других ячеек, ссылающихся на нее в формуле? Я не придумал ничего лучше, чем компенсировать отсутствие подпрограмм и циклов при помощи вкладок. Вы просто создаете в таблице столько вкладок, сколько циклов предполагается в игре и сколько раз за игру теоретически одна переменная может поменять свое значение. Тогда, например, ячейка во вкладке-2 будет наследовать значение той же ячейки во вкладке-1, претерпевать какие-то изменения и передавать свое значение в ту же ячейку из вкладки-3. Вот, например, как выглядят вкладки циклов в игре «Мировое господство».
По сюжету, игра всегда завершается через 6 лет, поэтому в таблице 6 вкладок с игровыми полями.
А вот, например, формула, которая вычисляет бюджет страны в третий год игры, суммируя исходный бюджет второго года и сумму прироста бюджета второго года:
Здесь E41 — это сумма в бюджете на начало года, X44 — сумма изменений в бюджете в течение года.
Или вот формула, которая выводит в ячейку на планшет игрока данные об экономическом состоянии города в зависимости от того, какой сейчас год на дворе. В зависимости от значения ячейки «счетчик лет» $F$1 выводятся значения одной и той же ячейки E36, но из разных вкладок, соответствующих тому или иному году.
Такое решение, к сожалению, дает возможность разрабатывать только пошаговые игры, состоящие из определенных циклов (сутки, день-ночь, месяц, год и т. п.). Причем количество циклов должно быть обозримым, иначе на написание кода уйдет целая вечность. Впрочем, если нет задачи сообщать игрокам промежуточные значения игровых параметров и отслеживать их динамику в процессе, с вкладками-циклами можно вообще не заморачиваться.
Распределение ролей
Иногда перед началом игры хочется мудро распределить роли, чтобы, например, наиболее активные персонажи достались более общительным игрокам, а роли с двойным дном — тем участникам, которые умеют блефовать и сдерживать эмоции. В игре «Экстренное совещание» эта задача тоже автоматизирована. Перед началом игры участники получают ссылку на анкету в формате Google Forms, где они отвечают на несколько вопросов о своих игровых предпочтениях.
Эти даные попадают в таблицу, где алгоритм на их основе распределяет роли между игроками.
Сбор данных у игроков
Как организовать сбор данных у игроков, если их 80 человек? Поначалу мне казалось хорошей идеей использовать для этой цели мессенджеры. У каждого игрока (или у каждого капитана команды) есть прямой чатик с ведущим, куда он может отправлять свои команды и распоряжения, оповещать о принятых решениях. Однако тестовые игры показали, что мессенджеры — плохая идея. Игроки начинают флудить, задавать кучу вопросов, ошибаться и отменять отправленные ранее распоряжения. В итоге скорость обработки данных падает, стек запросов разрастается, а игрокам приходится ждать по несколько минут, когда их распоряжение вступит в силу. К тому же большую часть игры участники проводят устваившись в свои смартфоны, а это не способствует живому общению и командообразованию.
Хорошим решением оказался сбор у игроков данных посредством анкет и карточек. Например, в «Чумовой Венеции» игроки в течение всей игры сдают ведущему заполненные карточки с формулировками типа «Паоло Алигьери подослал убийц к Джакомо Сфорца» или «Леонардо Бертолуччи соблазнил Лукрецию Медичи», а ведущему остается только ставить галочки в таблице на пересечении соответствующих имен и фамилий.
А в игре «День Выборов» команды старшеклассников сдают после каждого игрового цикла заполненные анкеты вот такого формата.
Данные в такой анкете максимально упорядочены, и ведущему требуется не больше 5 секунд, чтобы вбить их в таблицу.
Отстройка баланса
В ролевых играх важен игровой баланс: ресурсы всегда должны быть в легком дефиците, а различные инструменты по достижению целей примерно одинаково эффективными. Отстраивать баланс можно только вручную и только опытным путем, проводя серию тестовых игр. Чтобы не сойти с ума, меняя туда-сюда параметры в каждой формуле и в каждой ячейке, очень удобным решением является отдельная вкладка-справочник, где выведены все настраиваемые параметры, а формулы всей остальной таблицы ссылаются на них. При помощи справочника также можно, например, одним переключением чекбокса менять язык игры. Такая функция реализована в игре «Мировое господство».
Ввод данных в систему
Чтобы игра не провисала, ведущий должен иметь возможность вводить в таблицу данные максимально оперативно и эргономично. В гугл-таблицах можно настраивать формат ввода данных (dada validation). Самый быстрый и удобный формат — чекбокс. Правда, не все формулы умеют работать со значениями TRUE и FALSE. Поэтому значения чекбокса лучше сразу перевести в ноль или единицу в какой-нибудь соседней технической ячейке, а дальше уже с этими нулем и единицей делать все что угодно.
Выпадающий список — тоже очень удобный формат ввода, если в ячейке предполагается более двух значений. Наличие готовых вариантов в списке уберегает ведущего от опечаток, которые в игре могут сыграть критическую роль.
Вот пример полей для ввода данных в игре «Мировое господство».
Индикация событий
Ведущему важно вовремя замечать игровые события и реагировать на них. Так, в «Экстренном совещании» нужно вовремя замечать изменения в ячейках с номерами карточек, которые нужно выдать игрокам. А в «Мировом господстве» нужно вовремя сообщить игрокам, что город подвергся ядерному удару. Чтобы ведущий ничего не прозевал, можно использовать свойство ячейки conditional formatting (условное форматирование) — с ее помощью можно, например, сделать так, что при появлении текста «город уничтожен» ячейка самостоятельно красилась в красный цвет. В поле зрения ведущего окажется яркое красное пятно, которое невозможно не заметить.
Индивидуальная информация
В игре возможны ситуации, когда часть данных известна одной команде, а другой — нет. Например, в игре «Мировое господство» информация о наличии ядерного вооружения в той или иной стране является засекреченной. В этом случае удобно использовать отдельные устройства вывода для каждой команды, а на главный экран выводить только общедоступную информацию. Технически это решается как группа отдельных таблиц (свой файл для каждой команды), в которые из мастер-таблицы при помощи функции IMPORTRANGE подтягивается только нужная информация.
Кстати, Google Sheets предусматривает возможность экспортировать данные из таблицы в веб-интерфейс, так что при желании вместо сухой таблицы игрокам на планшеты можно выводить данные в виде красиво сверстанной и анимированной инфографики.
Аккуратные графики
В игре иногда вместо цифр хочется вывести на экран график, но стандартные диаграммы раздражают своей избыточностью. А еще тем, что они не умеют прилипать к ячейкам и всегда выглядят очень неаккуратно. К счастью, в гугл таблицах есть функция SPARKLINE. Эта функция отображает мини-график внутри ячейки. Он имеет определенные настройки, и его можно использовать для лаконичной визуализации некоторых данных.
Игровые новости
Иногда требуется не просто вывести цифру в ячейке, но и сформулировать мысль в виде грамотно выстроенного предложения (например, в разделе «Последние новости»). В этом случае на выручку приходит функция CONCATENATE, которая умеет склеивать куски текста с цифровыми значениями из разных ячеек. Вот как выглядит формула с использованием этой функции.
Подведение итогов
В «Мировом господстве» и «Чумовой Венеции» в финале игры объявляют не только главного победителя, но и команды, отличившиеся в различных номинациях. Для подведения итогов очень удобно использовать функцию MAX, которая вычисляет максимальное число в диапазоне. Ведущему ничего не надо дополнительно делать — достаточно просто прочитать с экрана названия победивших команд.