python

Атомный квест в Битцевском парке

  • понедельник, 30 сентября 2019 г. в 00:29:20
https://habr.com/ru/post/469345/
  • Python
  • Разработка игр




В связи с повсеместным хайпом по поводу Чернобыля в начале лета (по крайней мере в среде ядерной энергетики), а также гремящих словах цифровизация и геймификация, мы в ИБРАЭ РАН решили создать некоторое подобие квеста-приложения в котором концептуально моделируется эксплуатация энергоблока атомной станции и провести его тестирование в Битцевском парке.

Вводная


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

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

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

Старославянское капище


Медовое солнце


Приложение


Приложение написано на языке Python. Frontend (это ввод/вывод данных от игрока) создавался с использованием vuejs, jquery и flask. Backend (логика реактора и обработка событий) писался на чистом python. Связь между frontend и backend осуществлялась с помощью базы данных (SQLite). Базу данных оборачивали sqlachemy. Для развертывания приложения использовали Яндекс Облако.

Это не реклама
Но спасибо 4000 бонусным рублям, которые Яндекс дает для тестирования облака, этот бонус был очень кстати;)



Frontend


Серверная часть написана на языке Python (flask). Клиентская часть (интерфейс для игрока) создавался с использованием vuejs, jquery и немного рендера шаблонов страничек на сервере.
При переходе на веб сайт, участнику предлагается ввести код уникальный для каждой команды, после чего он попадает в главное меню.

Авторизация


Главное меню состоит из 5 элементов:

  1. Графики с параметрами реактора
  2. Ввод промокода
  3. Панель управления
  4. Карта
  5. Выйти

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

Графики

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

Промокоды

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

Панель управления

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

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

Все действия сторон описаны в таблице:

Таблица
Название Доступ Изменение мощности Время действия Стоимость Комментарий
авария реактор до 0 мгновенно Срабатывает автоматически с вероятностью параметра шанс аварии. Проверяется каждый шаг
иодная яма реактор -0.1/шаг мгновенно Срабатывает автоматически при нагрузке менее 50%
сброс админы мощность, скорость, все счетчики до 0, отмена всех текущих действий мгновенно
поднять стержни операторы +5 за все время действия 5 шагов 10
опустить стержни операторы -5 за все время действия 5 шагов 10
поднять расход операторы +5 за все время действия 10 шагов 5
уменьшить расход операторы -5 за все время действия 10 шагов 5
бор операторы -5 за все время действия 2 шага 25
АЗ-5 операторы мощность до 0 мгновенно 100
взорвать насос диверсанты +25 за все время действия 1 шаг 250
сломать насос диверсанты +25 за все время действия 10 шаг 50
пожар диверсанты до 0 мгновенно 300
надавить на операторов правительство +5 за все время действия 5 шагов 10
вирус диверсанты от -15 до 15 случайно 15 шагов 150
подкупить главного инженера диверсанты -20 за все время 20 шагов 10
подкупить главного инженера диверсанты +20 за все время 20 шагов 10
умолчать об аварии правительство -1 к счетчику аварий мгновенно 75
сэкономить на стержнях правительство +10 за все время действия 60 шагов 25
травануть операторов диверсанты 50% отмены действия операторов 12 шагов 150
внедрить шпиона в правительство диверсанты 50% отмены действия правительства 12 шагов 150
антитеррористическая операция правительство 50% отмены действия диверсантов 12 шагов 150
запугать персонал правительство 50% отмены действия операторов 12 шагов 150
провести инспекцию на станции операторы 50% отмены действия диверсантов 12 шагов 150
подкупить чиновников операторы 50% отмены действия правительства 12 шагов 150


Во вкладке карта, доступна карта из приложения Яндекс Карты, созданная при помощи конструктора карт (подробнее смотрите Подготовка к игре).

Карта


Backend


Весь backend написан на чистом Python. По сути весь код состоит из одного объекта Reactor (реактор, энергоблок, станция) с параметром мощности или состояния (state). Каждый шаг по времени step (задается вручную, мы задавали 1 секунду) состояние изменяется в зависимости от событий (events) произошедших на этом шаге. Стек текущих событий обновляется каждый шаг, обращением к базе данных, которая в свою очередь заполняется участниками игры из интерфейса веб приложения.

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

Для тестирования также создавались боты, которые действовали по некоторой стратегии. Для описания этих логик, также была создана фабрика стратегий.

Для подсчета очков также была создана фабрика, для того чтобы можно было варьировать логику подсчета от игре к игре. Базовая логика создавала одно победное очко на каждом временном шаге и отдавало его одной из команд в зависимости от уровня мощности на этом шаге (50-75 — операторы, 75-100 — правительство, 0 и больше 100 — диверсанты, в остальных случаях никому).

Квест


Подготовка



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

Для подготовки локаций, за неделю до события, в Битцевский лес был заброшен организатор. Он гулял по территории и находил интересные и выделяющиеся места, в каждом месте он совершал три операции:

  1. Записывал геолокацию (с помощью приложения Яндекс Карты yandex.ru/maps);
  2. Измерял качество сети (с помощью приложения Speedtest www.speedtest.net);
  3. Делал фотографию или видео локации.

В итоге было собрано 30 локаций (по 10 на каждую команду).

Яндекс Карты позволили сильно упростить создание карты, за счет конструктора карт yandex.ru/map-constructor. Он позволяет добавлять на карту свои локации, зоны и всяческие отметки. Затем интегрировать ее в свое приложение в виде кода JavaScript или iframe или разместить в виде ссылки, ну и на худой конец просто распечатать. Локации можно добавлять, импортируя их из XLSX, CSV, KML, GPX или GeoJSON файла. Единственным неудобством оказалась невозможность импорта локаций из обычных Яндекс карт прямо в конструктор (по крайней мере мы не нашли), пришлось перебивать их в xlsx таблицу и ее уже импортировать. Зоны с плохим качеством сети выделялись в конструкторе карт красной областью.

Карта


За день до игры (ну как водится) провели тестирование игры с участием 3 человек (по 1 от каждой команды). В целом особых замечаний не было, мы лишь немного скорректировали предварительно оценку в стоимости действий команд. Сразу отмечу, что сама игра выявила некоторые проблемы (о них в заключении), и вывод в том, что мы вряд ли могли бы узнать о них в тепличных комнатных условиях.

Игра


Утром 14 сентября 2019 года мы собрали участников в Битцевском лесу. В начале нашей спортсменкой, комсомолкой и просто хорошим ученым была проведена зажигательная утренняя зарядка.

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

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

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

Cпец. персонаж


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

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

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

  1. Быстрее повышать мощность (в какой-то момент команде операторов, имея большой запас победных очков было невыгодно ее повышать и они держали блок на низких нагрузках),
  2. Лучше регулировать мощность при высоких нагрузках (так как именно при них диверсанты начали делать всякие пакости, и операторы не всегда успевали на них реагировать).

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

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

Процесс


Вот она!


В итоге


Что-то получилось, что-то нет. Основными проблемами являлись не очень удачно подобранные параметры реактора, которые негативно влияли на геймплей:

  1. скорость роста шанса аварии;
  2. инерционность реактора.

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

Спасение реактора

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

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

Со статистикой игры можно ознакомится в reactor-quest.github.io, график интерактивный на (на персональных компьютерах), в нижней части можно выделить интересующий диапазон времени для более детального его просмотра.

Код приложения выложен на GitHub github.com/reactor-quest/reactor-quest можете свободно им пользоваться.

Всем добра и мирного атома, коллектив молодых ученых ИБРАЭ РАН!