[Перевод] Сложности переноса Papers, Please на мобильные

Mobile-Title


Я разработал Papers, Please в 2013 году специально с расчётом на десктопные компьютеры и управление мышью. В 2022 году десктопных компьютеров уже не существует и все компьютеры — это мобильные телефоны. Настало время обновить этого динозавра.

Эта статья из тысяч слов и мегабайтов изображений раскроет вам некоторые аспекты портирования игры с большого десктопа на маленький телефон. Отдавая дань прошлому, я написал эту статью как большой кусок текста с вкраплениями тегов img, а не превратил её в яркое видео. Ещё через девять лет я портирую этот пост в VR.

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

То же блюдо на другой тарелке.

Шаг 1: переход на Unity


Оригинальная Papers, Please была написана на Haxe/OpenFL — комбинации современного языка в стиле ECMA, похожего на Flash API, и системы многоплатформенной сборки. В 2013 году это была отличная среда для быстрой разработки игр, однако за прошедшие годы Haxe отошёл от своей нацеленности на Flash, а разработка обновлений для игры с учётом изменений в OpenFL требовала бы слишком больших усилий.

Когда я наконец-то решил взяться за этот порт, то сначала решил переписать игру на C#/Unity. После Obra Dinn я стал большим фанатом Unity, мне нравится в нём всё — редактор, структура сущностей/компонентов, система сборки и многоплатформенность.

Начав процесс, спустя несколько дней я понял, что хотя мне нравится C#, Haxe мне нравится больше. При создании игры я использовал множество базовых возможностей Haxe наподобие super enum и косвенной типизации, и постепенно становилось сложнее реализовывать всё это вручную на C#.

Я мог сохранить часть разработки на Haxe, но перейти с OpenFL на Heaps — ещё один движок и систему сборки на основе Haxe. При помощи Haxe/Heaps были разработаны Dead Cells, Northgard и несколько других игр, так что это полностью работающая система. Однако надо сказать, что для разработчика в моём положении удобство Unity сложно переоценить. Это замечательная система, если вы соло-разработчик, желающий создавать игры для нескольких платформ и отчаянно ищущий популярные, проверенные и поддерживаемые движок и систему сборки.

К счастью, Haxe — это транспилируемый язык, то есть можно писать на одном языке (Haxe), который перед компиляцией/интерпретацией на целевой платформе преобразуется в другой (Javascript, PHP, Python, C++, C#, Lua и так далее). То есть можно писать код на Haxe и транспилировать его на C#, который будет загружаться и компилироваться в Unity. Именно так я и решил поступить.

3382a7d08eae3fd33ecf10529383c9d2.png


Код на Haxe

cf4d6908ada3fe9a64c5efe74b18b421.png


Тот же код, транспилированный на C#

Первым делом я вырезал использование всего Flash-подобного API, предоставляемого OpenFL. Дерево отображения, события ввода, манипуляции с битовыми изображениями, воспроизведение звука — по сути, от всего, что не являлось базовой логикой игры. Затем я воссоздал это всё в новом коде. Цель заключалась в том, чтобы создать своего рода «чёрный ящик» PAPERS-PLEASE, получающий ввод игрока и выводящий в каждом кадре список прямоугольников для отрисовки и команды для аудио.

Наверно, это была самая интересная часть проекта. Полный Flash API всё равно был слишком обширным для Papers Please, поэтому создание нового движка специально под мои требования оказалось процессом освобождения.

Меня немного волновала производительность, поскольку большая часть OpenFL API была написана на C++, а я заменял её высокоуровневым кодом на Haxe. Однако требования игры крайне низки, а Haxe всё равно довольно высокопроизводителен, поэтому для получения хорошей частоты кадров мне достаточно было немного внимания.

Конечный результат требует минимальной оболочки хоста для передачи ввода в «чёрный ящик» и выводимых в каждом кадре прямоугольников и команд аудио. Благодаря такому минимализму я мог создать два хоста: один на Heaps, другой на Unity.

2027451a019b899b740e8058813a5966.png


Всё абсолютно понятно

Сам Haxe компилируется практически мгновенно и имеет хорошую поддержку Visual Studio Code, поэтому написание кода и его отладка на Haxe/Heaps — это простой и быстрый процесс. Для создания релизов я транспилировал код на C#, переключался на Unity и собирал проект там.

Шаг 2: интерфейс телефона


Теперь главным препятствием к портированию игры на телефоны был интерфейс пользователя. Papers, Please задумывалась как игра для больших экранов. Реальное разрешение игры смехотворно низкое (570×320), но эти пиксели должны быть большими.

Экран разделён на три области, которые всегда видны:

34a8daa78aa9344920e8f5f3eb5ab5fa.png


Контрольно-пропускной пункт, будка и стол

В 2014 году я отделил часть кода структуры интерфейса от базовой логики, чтобы создать версию игры для iPad. Благодаря некоторым улучшениям я смог сохранить эту схему из трёх областей и геймплей при помощи drag-n-drop. Самые большие изменения заключались в том, что области были наложены друг на друга вертикально с небольшой возможностью динамического изменения размера, а в области контрольно-пропускного пункта отображалось окно с горизонтальным скроллингом, а не вся область целиком.

01eaf2a0834b6795eb3930adfecbd7d6.png


Схема для iPad. Для просмотра области КПП необходим скроллинг.

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

33a1a38c9f4e238aa8f72eef75e560e9.png


Схема для Vita. Наложение будки и КПП, а также полноэкранный вертикальный скроллинг.

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

  1. Игровой процесс в портретном режиме.
  2. Все три области видны постоянно.
  3. Для чтения и перемещения документов не нужно щуриться, увеличивать изображение или обладать особой точностью.


Начав со схемы для iPad, я набросал небольшой макет для соотношения сторон экрана последнего iPhone:

c38494eda6895937e62160cd6e55472b.png


Игра, ужатая в соотношение сторон 10:22

Я пытался вносить некоторые перестановки и тому подобное. Преобразование контента 16:9 в 10:22 требует особого упорства. В одном из вариантов, который был отвратителен мне меньше других, лицо оказалось немного больше:

bc8b95ca3b3be64d0f692a82185a5f07.png


Большое лицо

Набросав кучу макетов, я пришёл к следующим выводам:

  1. Область КПП на границе в верхней части экрана должна скроллиться влево-вправо ещё больше, чем в версии для iPad. К счастью, всё важное помещалось на экран без скроллинга.
  2. Документы слишком маленькие, а стол слишком завален ими. Возникает фундаментальный конфликт между читаемостью и необходимостью достаточного пространства для упорядочивания предметов.
  3. Мне нравится большое лицо.


Огромное лицо выглядело так здорово, что я решил — документы тоже должны быть большими, и это открыло путь к важнейшим особенностям этого порта: больше никакого стола и drag-n-drop. На первое место я поставил читаемость и полностью избавился от требований упорядочивания документов:

ba3a93e6791deeb2138bf2bde8a254c9.png


Прощай, drag-n-drop

Стол, на котором игрок работал с документами, я заменил на два отдельных элемента: карусель для работы вблизи и подставка для быстрой навигации.

Карусель и подставка


1eb794e1bb102c24c2169e4153bd7f9a.png


Карусель выходит за пределы экрана в обе стороны

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

174b894c8af7a258e072968a39a85e23.gif


Навигация

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

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

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

Структура «карусель + подставка» стала фундаментальной адаптацией для телефонного порта и оказала существенное влияние на все остальные элементы основного интерфейса игры. Ниже я подробнее расскажу об этих изменениях и покажу их в анимированных gif.

Но пока пару слов о пиксельной сетке.

Пиксельная сетка


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

Для порта на телефон я остановился на разрешении 208×405, так игровые документы удобно размещаются на экране современных iPhone (без приставки Max). Откровенно говоря, не особо много пикселей, а область с КПП в верхней части экрана оказалась просто огромной.

d669781f8b4dcf709c83e0dbbf7f921a.png


Огромный КПП

Я бы предпочёл сохранить одинаковую плотность пиксельной сетки, но за всё приходится платить. В данном случае, жульничество с двумя пиксельными сетками решило множество проблем. При базовом масштабе 3x основные области будки и документов умещаются в 3x, а КПП — в более удобный масштаб 2x.

c15709301291f655bf13edc1e148be6c.png


КПП в масштабе 2x, всё остальное в 3x

В коде это масштабирование реализовано умножением на 2/3, а затем с округлением до целых значений в финальном буфере с масштабом 3x.

После избавления от проблемы с пиксельной сеткой осталась проблема масштабирования всего изображения на экран телефона. К счастью, истинное разрешение игры равно 208×450, а телефонные экраны (особенно retina) отлично справляются с пикселями. Сочетание целочисленного масштабирования и билинейной фильтрации здесь не особо вредит. Версия для телефонов выполняет регулировку соотношения сторон в определённом интервале, а затем масштабирует результат, чтобы он заполнил экран устройства.

52511e045e953033557e48a82fac87a3.jpg


Финальное целочисленное масштабирование и билинейная фильтрация изображения, отмасштабированные для заполнения экрана

А теперь рассмотрим особенности изменения базового интерфейса.

Слишком узко, не помещается


Множество из отдельных визуальных элементов не помещалось в базовую ширину экрана (208 пикселей). Я не стал их перерисовывать, а добавил дополнительную опцию масштабирования в 2/3, что упростило решение проблем, например, на экране заставки:

7f061a7b01d1447fe01edf9cb7268c44.png


Выборочное использование масштаба 2/3 на большом орле

С экраном вечера всё было чуть сложнее. На нём находилось слишком много информации, она легко умещалась в десктопные 570×320, но требовала совершенно новой структуры и условного масштабирования в 2/3, чтобы уместиться в 208×450.

c1feeb3a8d903c46516c9a8513eea794.png


Удобная десктопная структура экрана вечера

5f34ef448821dd4b9e110fd9e3084cc1.png


Изменённая структура экрана телефона с масштабированием в 2/3, чтобы поместились значки состояния, жетоны и так далее

Ещё одним большим элементом была газета, отображаемая в начале дня, она требовала масштабирования в 2/3 плюс более узкой структуры из трёх колонок вместо четырёх колонок из оригинала игры:

4bf7f66a0d1fcfc913476b54d0bb86bc.png


Изменённая структура и масштабирование, чтобы уместилась газета

Требование нового фонового изображения для газеты плавно перетекло в ещё одну базовую функцию движка, реализованную для порта: преобразование изображений во время загрузки.

Преобразование изображений


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

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

Один из примеров — это фон газеты, который является локализованным названием, «запечённым в изображение». Процесс превращения загружает и локализованное изображение для десктопа, и нелокализованное изображение, отформатированное для телефона, а затем копирует часть из одного в другое, создавая отформатированное для телефона локализованное изображение.

036b2b59541e646fca6a6daa32824169.png


Локализация заголовка газеты во время загрузки

Ещё один пример — страница бюллетеня с инструкциями по изучению документов. На ней функция превращения комбинирует локализованную нижнюю часть десктопной страницы бюллетеня с нелокализованной верхней половиной для телефона и создаёт локализованный бюллетень для телефона.

70608c183faeb58ce34e4bdf3708b6ec.png


Одно сюда, другое туда

Эти выполняемые во время загрузки изменения распространяются не только на изображения, но и на структуру некоторых документов. Например, справочник — самый широкий документ в игре; к несчастью, он не помещается в 208 пикселей. Он близок к этому, но не помещается целиком; кроме того, в нём есть важные вкладки и ссылки на перелистывание страниц, которые должны удобно располагаться на экране.

9459d89be2a131ca29eb34e7f8aeae8a.png


Оригинальный справочник, предназначенный для альбомной ориентации десктопов

Я хотел, чтобы вся область будки/документов имела одну пиксельную сетку, поэтому масштабирование в 2/3 здесь не подходило.

Здесь активно применяется функция превращения — она обрезает каждую страницу, перемещает все активные ссылки и поворачивает/перемещает вкладки, чтобы они уместились по ширине в 208 пикселей.

a1f7a9cdf48ec17661a877f6108db574.png


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

«Ваши документы»


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

0e78189d64782aae1d13de73f200476b.gif


Документы на стойке

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

Однако это показалось мне немного пассивным: терялось действие «ладно уж, я возьму их» из оригинальной десктопной версии, когда игрок перетаскивал их со стойки на стол для изучения. Я придумал такое решение: документы сначала должны всплывать на экране, чтобы игрок должен был коснуться их и поместить на подставку и в карусель. Порядок нажатия на них определяет их порядок в списке.

acc24a8ff086dc8906851990bbc24a85.gif


Всплывающие документы

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

a45f699cf5d696bc705765d2924b3194.gif


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

Собственный API для UI


Большой выигрыш от создания собственной системы UI для этого порта заключался в том, что я мог реализовать при помощи сенсорного ввода очень специфические действия. На первый взгляд, Papers, Please выглядит довольно простой 2D-игрой, но реализация всех взаимодействий с документами и интерфейсом через стандартные обратные вызовы событий ввода на Haxe/OpenFL требовали множества неудобных хаков. Новая система ввода не использует обратных вызовов и стала более чистой, что позволило реализовать логику ввода наложения и переноса элементов более удобным образом.

32224cf8290e8df0cc19af1db3812d45.png


Старая система событий, в которой логика обработки ввода разбросана по разным функциям обратного вызова

98fc38f5416480ebe6cbb8d1410765c3.png


Новая система событий react (), более централизованная и гибкая

Печати


В десктопной версии есть блок с печатями, выдвигающийся справа и нависающий над столом. Чтобы проштамповать паспорт, надо поместить его под печать и щёлкнуть.

00fda3ff05af6314e12d9636a93653a8.gif


Оригинальный десктопный блок с печатями

У меня возникли проблемы с адаптацией этого блока под телефоны, потому что (а) игрок не может просто перетащить паспорт под печать и (б) я не хотел лишать игроков удовольствия простановки штампов нажатием/касанием. Без второго требования можно было бы сделать перетаскиваемой саму печать, её бы просто перетаскивали на паспорт, где она ставила бы штамп. Но тогда игрок бы ставил штамп, отпуская экран, что мне всегда казалось неправильным. Вот некоторые из придуманных мной концепций:

28573f6a4cd20ab1a243edefe5baf043.png


Крепление к потолку, разделённый блок, лазерный датчик

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

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

42cd7bfab46b1e764371e82ce07dcfbf.gif


Открытие временного стола исключительно для печатей

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

4c62014dc461ef1ade26633972ebd3d3.gif


Качающаяся цепочка

Ещё и стол с ключами, почему бы и нет?


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

b67b6f84e426ead770a51425da1beae8.png


Временный стол с ключами для извлечения оружия

Зажим


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

9b7fb13ec1256e554c30f1c2517aefeb.png


«Головоломки»

Чтобы воссоздать эту функциональность в дизайне карусели для мобильных, я добавил зажим-«крокодил». Как и в случае с цепочкой стола печатей, этот зажим появляется только когда в фокусе карусели находятся документы определённого типа.

1d3b5ecc9fc55ded021c3ebbee77b394.gif


Зажим-«крокодил», появляющийся рядом с документом, который можно прикрепить

При касании зажима документ приподнимается над каруселью, после чего его можно перетаскивать по отдельности. Карусель по-прежнему можно скроллить под ним.

e9443a05bf5460c55d7f334f14003b08.gif


Действие зажима

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

Объявление «Разыскивается преступник»


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

9419724c9619f0bf4e59bb4700f1dc5e.png


Этих людей нужно арестовать

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

bbfb371ba5ce78ba44f3d567dddb7b1a.png


Знакомое лицо

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

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

e11c8301ddc08aed4af339a4e4055cc0.png


Фотографии висят на стене

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

1dc633fcd634251b232c65aff7f510ff.gif


Прикрепляем фото из бюллетеня к стене

Кнопки действий не помещаются на экране


Кнопки «ОТПЕЧАТКИ», «ОБЫСК» и «АРЕСТ» не помещаются на экране.

bdbfddbb7d93c66bb3da5a5cab3c5d53.png


Слишком широкие кнопки не помещаются по горизонтали в 208 пикселей

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

29296273aabd25b4a8a24d2ad11d1824.png


Здесь много места

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

8535b48d3fc4dd2b41eafd275c9433e3.png


Панель с кнопками. Это старая версия — в последнюю секунду перед релизом я удалил значки и выровнял всё по правому краю.

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

d55eae909ffa1827d488063d03c6e1d9.gif


Открытие панели мигающим рычагом

Эти кнопки полностью локализованы как изображения, поэтому повторное использование тех же кнопок и применение их во всплывающей панели сильно экономит затраты на процесс локализации.

Расширенный режим изучения


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

e6a39379ea57edbed6aa7cc63318f252.gif


Допрос о несоответствиях в десктопной версии

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

89e1bcc7cfcc83a4a47b0e91121387d4.gif


Режим изучения в версии для телефонов

Избавляемся от недостатков


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

Автоматическая сортировка

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

3b8cf1fc59b18e43805775e5769d42f9.gif


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

Умный сдвиг после выдачи документа

Единственное, что остаётся после штампования паспорта — это выдача путешественнику всех его документов. Выдача документа удаляет его из списка карусели, сдвигая в окно следующий документ. Первая реализация этой системы была наивной: если документ n пропадает, выполняем сдвиг к n-1. При обратной выдаче документов может выполниться сдвиг к документу, который не нужно возвращать, что заставляет игрока выполнять прокрутку вручную. Не очень большая проблема, но гораздо меньше раздражает, когда карусель сама переходит к следующему возвращаемому документу.

51c4518d4c3640c1d824c32f383803e9.gif


Сдвиг к следующему выдаваемому документу

Заглядывание

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

ad789403b7298660d0279513dccb3009.gif


Заглядывание в соседние документы

Тестирование автоматическим игроком


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

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

520d7058ad61703f6ebd6a96b6700392.gif


Автоигрок в действии: показывает последовательность действий, день, путешественника, время, память и так далее.

Автоматический игрок может управляться скриптами и выполняет последовательности действий («маршруты») для:

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


dac2101d345585a3b170d37ea7f0509f.png


Определяем план маршрута

А поскольку вся переписанная игра+движок модульны, можно выполнять этого автоигрока с максимальной скоростью, с графикой и без неё. На современном iPhone с рендерингом каждого тысячного кадра полный прогон примерно тридцати маршрутов игры занимает около пятнадцати минут.

Для создания этой системы потребовался целый месяц первоначальной работы, и приличное количество времени в процессе разработки. Откровенно говоря, это довольно много времени, но разработка и использование системы помогло мне найти и устранить в игре бесчисленное количество багов. Так как я вёл разработку на Mac при помощи Haxe/Heaps и собирал игру на Haxe/Unity, это также является бесценным способом проверить, что Heaps и Unity дают одинаковый результат, и что Mac/iOS/Android ведут себя корректно. Небольшие юнит-тесты могут проверить часть задач, но ничто не превзойдёт полные прохождения.

Многоплатформенность


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

2f4d7808c446da041b5d21399ff806cb.png


Обе мобильные схемы

Так как всё находится в одном двоичном файле, игре нужно знать, где она запущена, чтобы подбирать при запуске нужный интерфейс. На iOS это сделать легко, поскольку есть явная проверка на iPhone и iPad. На Android, к моему удивлению, отсутствует чёткое разделение на телефоны и планшеты, поэтому игра должна принимать решение на основании разрешения и DPI.

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

1217adca9ea7567271059b7877998d9d.png


Некоторым устройствам приходится выбирать

Окончательная структура выглядит примерно так:

  • iPhone: схема только для телефона.
  • iPad: схема для планшета по умолчанию, опциональная схема для телефона.
  • Устройство на Android: опциональные схемы телефона и планшета, по умолчанию используется определённая по параметрам.


Заключение


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

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

© Habrahabr.ru