UNH4CK3D — post-mortem

27 декабря 2016

Идея для игры на мой первый LD пришла немного раньше, чем была объявлена тема. Поэтому я решил участвовать в Jam и о теме не задумываться. Моя игра — браузерный симулятор хакера с реалистичными терминальными командами.

Перед LD

Поскольку я решил участвовать в Jam, меня на самом-то деле не сдерживали правила «сделать все в одного» и «все ресурсы должны быть созданы за 48 часов», поэтому я сделал небольшой набросок. Это были статичные HTML-страницы с щепоткой CSS и JS — экран входа в систему и рабочий стол с несколькими иконками.

Кроме того, я спросил нескольких своих друзей, и они согласились помочь мне, поэтому я создал приватный репозиторий на Github.

День первый

В субботу у меня были занятия в универе. К счастью, первой была лекция о том, что я и так знал, поэтому я писал код. Так появился прототип терминала: никакой верстки, только JS-код, который я запускал через консоль разработчика в Firefox. Конечно, это не настоящий шелл, но он умел парсить подаваемую на вход строку на аргументы (работая со "строкой в кавычках" как с одним аргументом и поддерживая несколько escape-последовательностей вроде n). Кроме того, работали пайпы |, потому что я уже придумал, зачем они мне понадобятся.

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

Потом я начал добавлять новые страницы с свой «интернет»: простые, вроде Mailbox (совсем статичная) и системных страниц browseros вроде settings, admin и no_internet.

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

Второй день

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

Во-первых, я начал работать над бэкендом игры, потому что хотел спрятать некоторые части игры от игрока. Поэтому я поднял легкую виртуалку и поставил туда LAMP, поскольку мой сайт хостится на таком же (а я собирался выложить игру на него). Тут в игру вступил PHP. Теперь игра состояла уже не из простых статичных HTML-страниц, и требовала запуска сервера. С другой стороны, теперь я мог сделать авторизацию и использовать базу данных, чтобы хранить прогресс игрока.

Бэкенд также отвечал за перевод: браузер пользователя отправляет серверу куку, и в зависимости от установленного значения я возвращают те или иные тексты в ответ. Я хотел сделать автоматическое определение языка пользователя по IP, но модуль PHP geoip не был доступен у меня на хостинге, поэтому впоследствии пришлось его открутить.

Далее были добавлены некоторые серверные системы: поиск, сеть и обработка URL. Их, конечно, можно было реализовать и на фронтенде, но тогда игроки могли бы смотреть в JS код и увидеть все доступные IP, URL и сайты в индексе поиска, чего я допустить не хотел.

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

Сеть — это набор объектов, представляющих собой узел. Каждый узел может иметь несколько имен (IP или текстовые имена) и набор открытых портов с некоторыми «сервисами» на них. С помощью этого я мог легко и просто добавлять новые компьютеры в игровую сеть, и различные сервисы на них (реализованы были только web и ssh).

Обработка URL парсит строку, введенную игроком в строке игрового браузера и ищет соответствие. Это просто набор захардкоженных строк (например, «search.com» перенаправляет на что-нибудь вроде «/pages/search/index.html»), но при обработке также учитывается сеть, так что если попробовать ввести <IP>:<port> в адресной строке, сервер попытается найти такой узел и посмотрит, есть ли на указанном порте веб-сервис. Если сервис там есть, будет отображена соответствующая страница.

Когда я закончил с этими системами, я стал работать над IRC, через который подается сюжет в игре. Я решил дать игроку выбор из нескольких заготовленных вариантов и добавить забавную механику нажатия клавиш, подсмотренную в SUPERHOT, для ввода выбранных вариантов. Еще я хотел, чтобы новые сообщения появлялись одно за другим, поэтому я получаю все новые сообщения через AJAX и показываю их по одному с указанной для них задержкой. Я не запоминал в базе данных статус сообщений, поэтому при обновлении страницы IRC мгновенно появлялись все новые сообщения. Еще круто то, что звук оповещений о новых сообщениях играет даже если уйти со страницы. Кстати, звук был создан с помощью sfxr.

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

День 3

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

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

Потом занялся первым заданием: надо перейти на страницу веб-интерфейса, залогиниться с помощью выданных логина и пароля и посмотреть на стикер на мониторе. Забавно, что все пытались зазумить картинку и разглядеть надпись на стикере, а я думал, что раз на стикере написано мелко, игроки вернутся в IRC и посмотрят, что там изменилось.

Второе задание было немного сложнее: для него требуется терминал, но я знал, что хакеры не станут объяснять игроку, как его открыть и как им пользоваться, поэтому мне нужно было добавить подсказок. Поэтому я сделал блог скрипткидди, который запостил скриншот открытого терминала и страницы в браузере, через которую можно этот терминал открыть. Там также есть подсказка по поводу использования curl и curl | dash (это такой шелл в browseros). Правда, подсказок про ssh я не добавил.

Далее я стал делать различные доработки: добавил плейлисты (стандартный «плейлист игрока» и электронный «от Tkachov»), перевод (потому что мой друг не совладал со всем PHP в моем проекте), нарисовал иконки, переименовал пару вещей, и т.д.

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

Прием игроков

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

Что удалось: похоже, игрокам понравилась идея, и многим полюбилось стучать по клавишам =)

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

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

В мою игру играли TVGS на своем стриме, а запись выложили на YouTube, так что если вам хочется посмотреть, держите:

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