Игровой редактор для платформера — постмортем

в 12:15, , рубрики: game development, iOS, Песочница, Программирование, метки: ,

Примерно 2.5 года назад мы задумали простенький проект — платформер с определенными свойствами: хардкорный, максимально динамичный, без стрельбы. Платформа — iOS, поскольку мы работаем только с ней — да и Андроид в тот момент еще не был серьезной альтернативой. За эталон был выбран не вышедший пока на тот момент Super Meat Boy.
Поскольку платформер — не та игра, где можно обойтись великой силой рэндом генератора, необходим был полноценный, мощный и удобный редактор уровней.

Игровой редактор для платформера — постмортем

Thus the story begins

Задумывалось это дело как простой “проект на месяц”, поскольку в успех жанра на мобильных платформах верилось не очень. Как мы его делали, тема отдельной большой статьи — но эта статья конкретно посвещена “эволюции” редактора, поэтому останавливаться на прочих деталях я не буду. Главное, что получилось так, что базовый прототип нам настолько понравился, что было решено “добавить фич”. А потом оказалось, что на создание уровней уходит раз в 10 больше времени, чем нам казалось априори, и проект незаметно вылился в самый грандиозный долгострой, который когда-либо выходил из нашего скромного коллектива (нас двое — программист и художник) — игра заняла без малого два года.

За это время игра немножко изменилась:
Игровой редактор для платформера — постмортем

Знакомьтесь, Редактор

Итак, редактор. Редактор уровней я придумал сделать прямо на айпаде — по двум причинам. Во-первых, мой “движок” не поддерживает других платформ кроме iOS. То есть, чтобы сделать редактор на PC, пришлось бы либо портировать весь “движок” и всю игру — чего не хотелось, либо писать редактор отдельно от игры, без возможности поиграть сразу — чего не хотелось также.

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

Он сказал — поехали!

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

Игровой редактор для платформера — постмортем

Идеология была проста — все начиналось с объекта номер ноль, который добавлялся специальной кнопкой. После чего, происходило клонирование до победного конца — новые объекты больше не добавлялись. Сначала копировался старый, потом ему выбирался индекс спрайта, и объект ставился в нужное место. Несмотря на примитивизм, схема работала неплохо. Забавно, но в течение 2-х лет мы выбирали индекс спрайта “на ощупь” — с помощью слайдера, в котором просто листались все спрайты подряд:

Игровой редактор для платформера — постмортем

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

Игровой редактор для платформера — постмортем

What (else) went right

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

  1. Одной из первых закоденных вещей была следующая штука — возможность дублировать текущий объект в любую из четырех сторон. С одной стороны это может казаться очевидным — но полезность этого была осознана не сразу — казалось расточительным тратить место на экране на целых четыре кнопки, которые делают одно и то же. Более того, если нажать на любую из кнопок-дубликатов, и не отпуская вести ее по экрану, объект стразу начинал перемещение в предположительно нужное место.
    Была даже пятая аналогичная кнопка — она копировала объект без сохранения параметров, выставляя дефолтные значения.
    Эта «фича» давала удобный способ расставлять повторяющиеся объекты, в частности, тайлы.
  2. Второй удобной штукой оказалась возможность удаления объектов с помощью простого тапа в определенном углу экрана — в нашем случае, в верхнем левом. Первоначально там находилась “корзина”, в которую нужно было помещать объекты drag&drop’ом, но выяснилось, что объекты нужно удалять постоянно — и драгэндроп уже недостаточно для этого быстр и удобен. Вышло так, что после определенного времени у нас выработалась определенная хватка устройства — айпад держался левой рукой так, чтобы большой палец аккурат приходился на виртуальную корзину, правая же рука управляла выделением объектов для последующего удаления. Это стало настолько естественно, что лишние объекты удалялись в считанные мгновения.
  3. Двойной тап для перехода в режим выделения объект(ов), по отпусканию объект фиксировался и редактор переходил в режим перемещения, который прекращался либо повторным двойным тапом, либо переходом в режим перемещения по карте. Это позволило во-первых видеть объект, который мы перемещаем, не закрывая его пальцем, а во-вторых уменьшить вероятность случайного перемещения.

Пожалуй, на этом гениальные озарения заканчивается, и начинается обширный список того, что было, что называется, “learned in a hard way”. За деревьями не видно леса, проект никак не хотел заканчиваться, и мы попали в тот самый вечный цикл, знакомый по статье о Starcraft — игра все время была “за месяц до релиза”. А поскольку до релиза оставался “месяц”, тратить время на усовершенствование редактора не хотелось, что стоило десятков, сотен потерянных впустую часов.

What went wrong, very very wrong.

  1. Undo. В редакторе и поныне нет Undo. Почти нет — возвращается одна операция перемещения — и все. Казалось не столь важным, а реализовывать вроде бы долго — заводить общий пул для каждой операции, динамически выделять мегабайты памяти для сохранения масштабных изменений… А первоначально отсутствие Undo компенсировалось недостатком номер 2, о котором ниже. В результате многие часы (в общем итоге) были потрачены на восстановление объектов, случайно зацепленных большим, неуклюжим пальцем. Или на удаление случайно сдублированного “мимо” десятка объектов. Внимание эта проблема к себе не привлекала, поскольку возникала не то чтобы совсем часто, но оглядывась назад, c сожалением признаю — отсутствие данной операции потратило многократно больше времени, чем заняла бы ее реализация.
  2. Массовое выделение. Да, объекты нельзя было выделять больше чем по одному. Не казалось важным, казалось сложным для реализации — та же самая проблема что и в первом случае. Фактически, это привело к тому, что в игре до финальной стадии отсутствовал copy/paste, а значит — каждый из порядка 50,000 объектов в игре был поставлен вручную, в свою уникальную точку — кроме тех случаев, когда они скопировались в рядом стоящую ячейку с помощью тех самых команд дубликации. Профитом здесь является бОльшая уникальность уровней — поскольку нельзя было копировать целиком куски уровня, все создавалось каждый раз заново. Но как недостаток — явный перерасход времени, причем в разы.
  3. Анимация объектов. Все параметры задавались с помощью слайдеров, хотя кое-какие “хелперы” все-таки были. В результате, если нужно было, чтобы по триггеру с определенного расстояния срабатывала анимация — и заканчивалась ровно там, где нужно, и ни пикселем дальше, уходило по 20-30 итераций на ручную подгонку параметров. В результате бОльшая часть уровней не может похвастаться хитрой или интересной анимацией, и уровни большей частью статичны.
    Логичным и простым решением сейчас кажется простое перемещение объекта в редакторе, с автоматическим вычислением нужной скорости, но на тот момент столь простой мысли в голову не пришло.

  4. Точность. Самым, пожалуй, большим бичом была следующая проблема — недостаточная точность перемещения объектов — невозможно было переместить объект в нужную точку — из-за тачскрина и пальцев в качестве устройства ввода. Для “решения” этой проблемы было реализовано две вещи — сетка (snap to grid), и невозможность переместить объект на нечетный пиксель (то есть, фактически, сетка с величиной ячейки = 2).
    Это частично решало проблему, но к сожалению некоторые объекты были “неправильного” размера, и к сетке не стыковались, кроме того иногда можно было забыть заранее включить сетку, и целая куча объектов оказывалась мимо этой самой сетки — а в результате приходилось либо фиксировать позицию объектов к сетке “ручками”, либо “забить” на сетку и играть в веселую игру “попади пальцем в пиксель по обоим координатам всего лишь с 15го раза”.
    Правильное решение, на которое ушло больше года, оказалось простым фиксом из пяти строчек — который по нажатию определенной кнопки снижал скорость перемещения объектов в несколько раз.

  5. Хоткеи. Выяснилось, что самые частые операции это:
    — поворот объекта
    — изменение ориентации (flip) по осям x и y
    — отключение коллизий
    — изменение zIndex (порядок отрисовки, который задавался вручную)

    Для них требовалось от одного до трех тапов. Необходимо было выделить объект, а потом вызвать панель редактирования параметров, которая частенько была закрыта, так как закрывала приличную часть экрана, и соответственно непосредственно переключить объект. Много времени уходило на это, а разместить эти операции в виде отдельных кнопок не получалось — они не влезали на экран, место со всех сторон кончилось, а делать второй ряд не хотелось — это бы уменьшило область видимости. Для решения этой проблемы было принято решение “прикрутить” внешнюю клавиатуру. Был куплен переходник для USB клавиатуры (в лучших традициях Штирлица называющийся Camera Connection Kit), и потрачено несколько бесцельных ночей в попытках заставить ее работать. Получилось с помощью “хака” — невидимой текстовой формы величиной в 1 пиксель. И тут оказалось, что работать одновременно с айпадом и внешней клавиатурой — неудобно. Нужна третья рука — одна держит устройство, другая манипулирует объектами, третья нажимает кнопки.
    “Фича” осталась невостребована.

  6. Интерфейс в целом. Не казалось важным или необходимым, но интерфейс, не сильно мешая в целом, сильно проигрывал в потенциале и расширяемости. В данный момент я, начиная новый редактор с нуля, первым делом позаботился бы о следующих вещах:
    • Удобные выпадающие меню, для выбора команды по отпусканию.
    • Панели, вылезающие из-за экрана по “свайпу”, подобно тому как вызывается панель “Notifications” на iOS.
    • Циклическая прокрутка набора кнопок — чтобы можно было выбрать нужные тебе конкретно сейчас операции, и таким образом вместить больше команд “быстрого доступа“.
    • Multitouch для частых команд типа flip, rotate, scale, zoom. Попытка мною предпринималась в самом начале работы, но я ей уделил недостаточно времени — были получены неудовлетворительные результаты и работа отложена до лучших времен, которые никогда не настали — а зря.

In the end.

В конце концов игру мы выпустили, и все кончилось хорошо. Ну, почти — с продажами пока не совсем получилось, но мы работаем над этим. Пока можем лишь скромно похвастаться невероятно высоким средним рейтингом в Google Play — 4.9 единиц, то есть тем фактом что игра людям не нравится, а нравится очень и даже весьма.
Идея создавать редактор внутри игры и исключительно для ipad — спорно, но была не самой плохой.

Игровой редактор для платформера — постмортем

Автор: jaguard

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js