Удобный кусок мыла: как мы делали контроллер из телефона
Нам нужно было сразу 6 геймпадов к одному телевизору. Логичным виделось решение с телефонами, в которых есть всё нужное: и кнопки на экране, и связь, и камера, и гироскоп. Короче, телефон умеет делать вообще всё, но при этом всё из этого он делает отвратительно плохо.
Задержка ввода до 0,7 секунды — легко!
Если пользователь — на даче, то из-за лагов Интернета события могут прийти не в том порядке, как он нажимал на кнопки. Не уметь держать открытой сессию — пожалуйста. Прервать сессию при отключении экрана — держите! Постоянно отваливаться с веб-сокета — не проблема!
Короче, это невероятно бесячая штука, но для нас это было ровно то, что нужно.
Потому что мы перенесли настолки на телевизор. Начали с простых викторин-квизов, где каждый может выбрать свой вариант ответа с телефона. На телевизоре — видео, звук и вопрос, у вас на телефоне — варианты ответов.
Более интересны были механики типа «Имаджинариум» или «Крокодил», где каждому на телефон можно доставить кусочек закрытых данных, которых не видят другие игроки: это то, что решалось на столе картами. Ещё прекраснее — механики, где игрокам надо что-то считать: теперь это всё можно было автоматизировать на телевизоре.
В общем, благодаря этим кускам мыла мы теперь один из очень желанных для провайдеров источников видеоконтента. Но сегодня — не про это, сегодня — про эргономику телефона и что стоит знать на берегу, если вы захотите использовать его как контроллер.
Нова ли идея?
Нет, ни разу. Использовать телефоны вместо геймпадов и других контроллеров в массовых играх придумали давно. Есть два проекта, где можно поиграть в аркады со своих телефонов. В обоих проектах очень высокий порог входа: надо установить приложение на телевизор или приставку (смотря что из этого отвечает за «смарт» и умеет считать), потом — на телефоны, потом соединиться напрямую через одну вайфай-сеть. Только тогда будет более-менее быстрый отклик, но всё равно отзывы полны рассказов о том, что это тормозит намного сильнее, чем облачный гейминг. Если вы достаточно стары, то застали это в игре «Позвоните Кузе», когда телезрители со всей страны познакомились с задержкой телефонной сети и распространением аналогового сигнала, местами — через спутник.
Самые известные проекты с контроллерами-телефонами — Kahoot!, Jackbox Party Games,
AirConsole. Ещё «Нетфликс» недавно анонсировал свой игровой пульт в телефоне. Он пока ещё не в паблике, но все очень его ждут и интересуются, что же будет дальше. Вот ещё полезная публикация с обзорами.
Ещё телефоны как пульты используются на спортивных матчах — у нас в стране всё для этого есть в Краснодаре, а так на играх крупных футбольных и баскетбольных лиг в далёких странах можно в начале матча отсканировать QR-код с большого экрана и за что-то голосовать. Вот квиз на стадионе, например. Призы выдаются, кстати, не фантиками по e-баллам, а по номеру билета, надо показать свой билет с уникальным ID.
У нас — настолки. Точнее, уже нателевизорки.
Настолки изначально разработаны под человеческие интерфейсы. Человеки вводят максимум два байта в секунду, считают примерно со скоростью один разряд в пять секунд, то есть с точки зрения вычислений крайне ненадёжны. Особенно на вечеринках. Поэтому настольные игры всегда жесточайше оптимизированы под то, чтобы минимум времени уходило на обслуживание игры и максимум — на взаимодействие игроков.
Когда в уравнение добавляется телевизор, можно пользоваться его процессором. Он берёт на себя все расчёты игровых состояний и даже может кидать рандом без кубиков. И мгновенно. Он раскладывает игру, полностью перестраивает игровое поле за секунду, перемешивает и раздаёт карты мгновенно — в общем, все технические вещи делает куда быстрее. Второй вариант — использовать его как экран со связью и считать всё на сервере.
Оптимизация уходит с расчётов на интерфейсы, с одной стороны, а с другой — все наши игры походовые. То есть нет ни одного экшна или аркады. Мы буквально сто лет оттачивали до предела умение делать интересными дискретные игры. И ровно для такой ситуации телефон идеален даже без приложения.
Ну, по крайней мере мы так думали до первых полевых тестов.
Первые полевые тесты
Начали с очень простой игры — викторины. Пришёл Тимофей и сказал, что самое крутое для вечеринки — это раскрытие одного из величайших экзистенциальных страхов человека перед старением. Короче, принёс вопросы, где показывают фотографию подростка, а вам надо угадать, что за актёр или политик потом из этого вырос.
Процесс следующий. Хозяин телевизора заранее ставит на него приложение — осознанно или выбирая викторину из каталога. Например, на тех же «Сяоми» вы выбираете развлечение, а не софт. Например, если выбрать игру «Квиз», то телевизор сначала оценит, от какого приложения этот контент, потом поймёт, есть ли оно, если нет — попросит подтвердить установку, поставит и прокинет внутрь диплинк.
Можно использовать не телевизор, а запустить всё то же самое на планшете или ноутбуке с веба. Можно шарить экран с планшета с веба, веб-вьюхи тоже нормально работают.
Запущенное приложение или веб-вьюха показывают QR-код, который надо сосканить, чтобы соединить всех игроков в одну сессию.
Мы думали, что тесты начнутся где-то дальше, когда пойдут вопросы. Нифига подобного.
1. Люди не умеют сканировать QR-коды
Для нас с вами это суровая обыденность, и понятно, что нужно открыть приложение камеры, навести телефон на код, и дальше случится магия.
У обычных людей такого шаблона поведения, как выяснилось, нет. Точнее, не у всех. Ещё у части людей шаблон, может, и был бы, вот только приложение камеры не поддерживает распознавания кодов.
Поэтому первое, что мы сделали, — купили короткий домен и добавили ссылку буквами, чтобы люди могли входить в сессию.
У других проектов, использующих телефоны как контроллеры, есть упрощение определения домашней сети по IP. Предполагается, что если люди ломятся примерно из одного диапазона примерно в одно и то же время, то это одна компания. У нас на практике это не работает, потому что многие используют собственный аплинк телефона. Что хотим сделать — давать ссылку первому залогинившемуся, чтобы он шарил её в «Телеграме», «ВКонтакте» или «Ватсапе». Судя по тестам, этот способ в разы более действенный, чем QR-код. Есть другой путь — попросить на входе номер телефона и прислать туда ссылку на комнату. Пока ещё идут дискуссии, ухудшит или улучшит это UX. Для нас выглядит жёстко из-за раскрытия номера телефона, но, кажется, это смущает именно ИТ-аудиторию. Есть странные способы авторизации вроде семплирования звука или состукивания телефонов: было бы круто заорать: «ТАГИ-И-ИЛ», чтобы все микрофоны услышали сэмпл. Но для этого нужны нативные функции телефона.
По сканированию кода открывается вкладка браузера, которая и будет клиентским фронтом. Это single page application на веб-вьюхе, которая поддерживает веб-сокет-сессию.
Если что, телефон преобразовывается в пульт несколькими разными способами начиная от прямых команд в инфракрасный пульт и заканчивая соединением по Wi-Fi с неким TV-API. Всё это очень локально и привязано либо к железу телефона (у вас есть IR?), либо к производителю телевизора. Поэтому единственный нормальный способ — делать сторонний сервер и вешать сессии телефонов на него плюс соединять его с терминалом-телевизором.
Приложение телевизора может делать достаточно «тяжёлые» вещи вроде видео, звука и анимаций. Мобильные страницы на телефонах должны быть супероптимизированы под EDGE-соединение и не содержать ничего лишнего. В идеале — текст и контролы + CSS. Визуал — через тот же CSS.
2. Не все браузеры поддерживают веб-сокеты
Казалось бы, 2023 год на дворе, лунная программа, победили антиваксеров и мракобесов, 25 лет исполняется стандарту IPv6, а тут такое!
Помните, что такое Android Browser? Ну так вот, он не поддерживает сокетов, и сессия дропается сразу после логина. У кого осталось такое легаси? Из тех, кто логинился, — примерно у 0,4% людей. Поиграть они не смогли. По нашей оценке, до 2% браузеров сейчас криво работают с сессиями, но, к счастью, на старых или очень дешёвых телефонах.
Откуда эти 2%? Мы без понятия. Даже несмотря на то, что большая часть пользователей — люди с топовыми телефонами, они умудряются то открыть сайт в веб-вьюхе стора, то сделать что-то ещё крайне неочевидное. Ждём запуска нас через приложение карт и со стиральной машины.
В целом это не проблема, просто нужно объяснить человеку, что идёт не так, потому что без правильной индикации он будет заходить и сразу выбрасываться.
3. Люди не умеют договариваться
Дальше, когда все сессии установлены, можно выбирать игру из каталога. Это происходит на телевизоре.
Сделать это можно пультом от самого телевизора, управляя приложением, а можно — с телефона, потому что там появляется джойстик:
Кстати, этот джойстик — первое, что можно попробовать без захода в игру, подключается почти сразу. Ощущения такое управление вызывает довольно интересные.
Нам в принципе в голову не пришло, что 8–10 человек в комнате способны произвести столько хаоса. Где-то трое-четверо разбираются, что происходит, и начинают активно участвовать в выборе игры. В результате на телевизор приходит четыре-пять команд сразу, и он выполняет их все.
Почему? Ну, в части случаев люди спорят, какую игру ставить. А ещё в части кто-то хочет посмотреть каталог, кто-то помогает листать и так далее. В общем, когда очевидно, что надо нажать «вправо» и «ОК», это нажмут на двух-трёх разных пультах в течение пары секунд. Не со зла. Это примерно как пользователь помогает при RDP-поддержке тыкать в кнопочки своей мышью. Только их сразу несколько.
Тут мы вспомнили, что даже когда два человека идут за водой, надо назначать старшего. Точнее, что даже на «Сеге» были «админский» джойстик с кнопкой Start и ущемлённый в правах второй джойстик.
Учитывая поток жалоб, сделаем один мастер-телефон. Это сложно, потому что добавляет шаг на поиск владельца телевизора или учредителя вечеринки. Но похоже, что это нужно, потому что можно подраться, ещё не доходя до выбора игры. В последних релизах кто первый подключился, тот и хост — только он может запускать игру. Но осталось, что остальные могут осуществлять навигацию по каталогу и это нужно убирать тоже, чтобы снять проблему.
Что самое чертовски смешное, люди не считают, что проблема — в них. Это же логично: раз не получается выбрать — значит, приложение глючит. И их точка зрения предельно понятна.
4. Браузер — не для нервных игр
Вот у вас есть простая, казалось бы, задача — выбрать один из вариантов ответа:
Что тут может пойти не так? Ну, для начала люди будут скролить эту страницу. Заблокировать её в силу браузерной природы нельзя, поэтому браузер будет время от времени открывать строку с адресом. Ладно, тут люди понимают, что происходит, и просто не обращают на неё внимания.
Теперь представьте, что вы выбрали ответ, а потом через секунду поняли, что он не тот. Это случается гораздо чаще, чем принято думать. Что в таком случае делать? Правильно: нажимать кнопку «назад»! Это же понятный шаблон поведения: ой, не то, срочно назад. Галя, у нас отмена!
Браузер, естественно, отбрасывает на домашний экран, потому что перехода между страницами в SPA нет. Это можно победить несколькими жёсткими способами, но в текущем релизе это так.
5. Кусок мыла с медленным аплинком
Телефон — очень неточная штука. Люди — очень неточные операторы. Пьяные взволнованные люди, играющие на Новый год в викторину, очень редко способны правильно пользоваться интерфейсами. Трезвые — тоже, особенно, если есть таймер — 30 секунд на ответ.
Во-первых, если соединение медленное (а оно очень часто медленное, напоминаю про 2G/3G на дачах), то будет задержка между нажатием на кнопку и реакцией на это нажатие. Поэтому пользователь может решить, что не нажалось, и нажать второй раз. Во-вторых, он просто может тапнуть так, что сгенерируется двойное нажатие.
Поэтому важные вещи:
1. Ничего не делается одним нажатием.
Например, надо выбрать вариант и нажать внизу «отправить». Иначе будут случайные тапы просто потому, что человек хотел перехватить телефон поудобнее.
2. Нужен сервер очередей, позволяющий разбирать такие ситуации, как «пришло сообщение об отправке ответа, затем пришло сообщение о выборе варианта № 2», и команды могут легко поменяться местами в пути до сервера.
3. Никакое двойное нажатие не должно приводить к двойному действию. Например, если человек нажал «отправить», то может сгенерировать двойной тап и сразу же отправить следующий ответ. Поэтому мы используем микротаймеры на кнопках, деактивирующие их на одну секунду после появления. И стараемся делать так, чтобы новые кнопки не появлялись ровно под старыми.
4. При нажатии контрол должен менять состояние внутри логики фронта. Не так, что на OnClick он сбегал до сервера и спросил новый статус, а так, чтобы это было прямо на клиентской стороне, чтобы человек сразу видел, что клик прошёл. В некоторых ситуациях это требует доработки механики игр, чтобы интерфейсы были более читаемы под такое требование.
5. При игре на таймер при отправке в последнюю секунду нужно понимать, что есть задержка ввода (от телефона к игровому серверу) и задержка вывода (от игрового сервера до телевизора). Поэтому как активные поля кнопок в UI делаются больше визуального поля, так и таймер по факту делается больше фактического. Эмпирически мы подобрали задержку в 0,7 секунды — ровно на неё все таймеры больше.
6. Возможна коррекция по запоздавшим пакетам. Сервер очередей, соответственно, может принять пакет после таймера (отправленный до истечения таймера), и когда на телевизор уже выводятся результаты ответа, откорректировать в пределах нескольких секунд запоздавший.
6. Питание и сессия
Человек может в любой момент отключить экран телефона. Во-первых, кнопка очень удобно лежит на торце, и в попытке перехватить телефон поудобнее люди часто отключают экран. Андроид тут же сбрасывает сессию, iOS в некоторых случаях её удерживает.
Во-вторых, бывают игры, где вы ждёте других людей. Есть люди, которые очень-очень беспокоятся за заряд и предпочитают выключать экран телефона на 30 секунд, пока ходит Вася.
Сначала мы делали так: в момент входа в игру проверяли активность игроков, дальше при отключении любого из них останавливали игру и ждали, пока он не подключится обратно. Само возобновление сессии реализовано хорошо: достаточно попасть обратно на мобильный сайт, там он вычитает из куки, что случилось, и вернёт человека в игру.
Но вот частота пауз бесила просто до невероятности! Во-первых, есть микроотвалы всё из-за той же нестабильности соединения. Там можно и нужно прописать тайм-аут, когда мы считаем пользователя отвалившимся, а не создавать событие каждый раз. Задержки в 0,3–0,5 секунды вполне хватает. Это тоже обрабатывает сервер очередей.
Во-вторых, мы использовали старый добрый настольный принцип расчёта аптайма и учли поведение пользователей, выключающих телефон в свой даунтайм. То есть стали останавливать игру, только когда нужно критичное решение. Например, если показывается какая-то ситуация, то мы не остановим игру, а если надо всем проголосовать по обсуждению этой ситуации — остановим, пока все не подключатся.
То есть только в тех местах, где игрок становится блокером, мы ждём его переподключения. Это решает 90% ситуаций.
Следующая проблема возникает с тем, что вообще-то люди могут спокойно встать во время игры и уйти: кто-то — курить, кому-то надоело, кому-то надо позвонить бывшей. Один из бета-тестеров рассказывал: «Ну, я ответил на 10 секунд раньше, подошёл к столу, взял чипсину и выпил. Следующее, что помню, — утро». Если это викторина, то тут всё просто: надо остановить игру на «Ой, Зиновий отвалился», и если всем понятно, что Зиновий не вернётся, то дать игрокам право его кикнуть. А вот в случае с более сложными играми, где количество игроков определяет баланс, нужны какие-то другие механики. Мы пока не знаем, но кики покрывают почти все нужные ситуации. Точнее, есть игры, где это важно, а есть, где терпимо.
7. Автозамены
Одна из очень частых механик викторины — у вас поле ввода текста, 30 секунд, и надо успеть напечатать ответ. Да, он обычно простой, например: «Титаник». Но автозамена только и ждёт момента, когда вы расслабитесь! Например, «аппетит» может легко приехать вместо «аппендицит».
Соответственно, на проверке ответов нужны:
- Проверка расстояния Дамерау-Левенштейна до исходного слова.
- Словарь самых частых опечаток из-за того, что пользователь не знает точного написания слова или имени.
- Словарь синонимов.
- И — та-дам! Словарь автозамен телефона на это слово.
В общем, если вы всё это победите, то телефоном внезапно можно будет пользоваться уже так, как пользователь хочет, чтобы он работал, а не как он по факту сделал.
Система в целом
Итак:
- Экран — приложение на телевизоре или приставке либо страница в браузере на ноутбуке или планшете.
- Контроллеры — телефоны с мобильными сайтами в системном браузере.
- Сервер — связывает экран и контроллеры, реализует сервер очередей и корректирует ошибки ввода разными способами.
- Связь — любой аплинк до сервера.
Можно ли всё это упростить и занести сервер в приложение на телевизоре или приставке и соединять напрямую? В целом да. Но это требует очень сложного согласования интерфейсов и, скорее всего, приложений на каждый телефон. Это создаёт практически невероятный порог входа, если вы на вечеринке и хотите быстро начать играть. Пока это не наш путь, поэтому надо мириться с коррекцией ошибок.
Что можно использовать из возможностей телефона? Ну, любой UI на странице браузера, то есть какие угодно кнопки, таймеры, варианты ответов. Очень легко добавляются механики вроде листания карт, увеличивания чего-то, голосований и разных вводов. С анимацией и графикой плохо — видеокарты телефонов и процессоры позволяют, а вот каналы частонет, лучше отправлять сверхлёгкие картинки, если варианты ответов с ними. Распознавание голоса — только системное для упрощения ввода текста и на вечеринке в шуме работать не будет. Данных гироскопа у нас нет, тут нужно приложение. В целом легко получить данные камеры, но загрузка аватарки с селфи на телевизор пока не готова, в беклоге. AR и NFC не нужны. Геопозицию можно получить, но не очень точную. В общем, в основном нам нужны тачскрин и аплинк.
По телевизорам и приставкам тоже есть весёлые моменты. В них ставят самое дешёвое железо из возможного, лишь бы показывали стриминг. Это значит, что если ваш контент не оптимизирован под приставку (а видео из браузера редко оптимизировано), то он будет тормозить.
Разные сторы (мы сейчас есть в «Аппсторе», «Гугл плее», «Русторе», на приставках «Сбера» и «Ростелекома», заходим в «Кинопоиск») несильно влияют на ситуацию, всё равно это в итоге выливается в две основные операционки.
Тормозить может и канал. В нашем случае это касается HD-видео и анимаций. С видео просто: обычно есть аппаратный кодек. Приходится внутри приложения телевизора делать специальный измеритель скорости Интернета, который определяет, какую версию получать с CDN: у нас там градации от 1080p до 360p, причём это режется прямо на стороне CDN. Готовьтесь учиться работать и с этим. Вообще у крупных приложений вроде «Ютуба» есть договорённость с производителями телевизоров, и под них есть особые оптимизации и механики. Например, на некоторых телевизорах при расшаривании экрана с телефона страница «Ютуба» показывается стримом с телефона, а при разворачивании видео в полный экран (когда пропадает интерфейс) прокидывается уже ссылка на тот же файл в CDN, и телевизор его подхватывает, а не использует стрим телефона. Там есть проблема с тем, что те же стриминговые приложения постоянно измеряют состояние канала, а мы не очень часто, поэтому сегодняшнее решение — есть настройка принудительного назначения высокого или низкого качества: это когда сеть лагнула, а потом заработала, и можно переходить на HD.
Что касается анимаций, то тут мы утилизацию процессора и памяти измерить не можем, но знаем, что есть куча приставок с 1 Гб оперативки, и хорошо, если из этого гигабайта хотя бы 100 метров остаётся на само приложение. Равняемся на них, поэтому градации настроек графики нет.
Естественно, никаких подключений родственников по видео-конференц-связи: телевизоры и приставки этого просто не тянут, да и камеры у них обычно нет.
Про разработку
Про разработчиков надо рассказать отдельно. Стояла задача показать провайдерам вроде «Ростелекома», «МТС», «Мегафона», «Яндекса», что у нас есть новый тип визуального контента. Нужен был прототип, который затащит внешняя студия. Обычная веб-студия для этого вообще не подходила, потому что у каждой есть специализация: кто-то умеет разуплотнять «Битрикс», кто-то божественное делает на «Вордпресс» (вы можете смеяться, но это огромная доля рынка) и так далее. А тут нужны были сразу мобильная разработка, веб-разработка, клиент-серверные операции, нормальный бек и ещё неведомая хтонь в виде смарт-тв, где сюрпризы могли быть где угодно.
И тут нашёлся Валера Комягин luckydon. Валера — идеальный советский инженер. Закончил МИЭТ, научился разбираться в сложных системах и чинить их проволокой, может понять любую проблему и найти решение. При этом он нифига не умеет в маркетинге и постоянно делает то билетную систему, то клиринг, то парольный менеджер. Короче, у него компания по разработке SVK.Digital на 40 человек, и 20 лет они делают что-то, что можно описать как «всякая фигня». Валеру сначала мы хотели было зарезать в Counter-Strike, но потом узнали как человека. Кстати, когда Тимофей вышел на него поспрашивать про разработку, и вдруг выяснилось, что именно книга Тимофея «Энциклопедия рекламы» когда-то стала для Валеры воротами в Интернет. Это были те далёкие времена динозавров, когда Тимофей рисовал первый флеш-баннер в Рунете со своим промо.ру. Короче, они договорились. Потом узнали про Серёгу Филиппова, который CTO и соучредитель в той же компании. Серёга лет этак 10 занимался тем, что накапливал в компании конвейер по запуску продуктов. И среди прочего они уже делали что-то похожее с телефонами в Голландии для сети ресторанов, поэтому какие-то куски фреймворка у них были. И именно благодаря команде Валеры и Серёги во всё это сейчас можно более-менее нормально играть, потому что в отличие от ожидаемого поведения команды разработки они ещё затащили продуктовую часть и очень радели за UX. Собственно, большая часть UX-доработок придумана именно на их стороне.
В итоге этот скользкий кусок мыла теперь помогает веселиться.
Пример цены на игру
Попробовать всё это можно вот тут: pstv.ru. Там есть бесплатные игры, есть платные (и, кстати, на телевизорах надо тщательно отслеживать время внутри каждой игры для выплаты роялти авторам) — так вот, код JRESHRST разблокирует на месяц все платные игры тоже. Самое главное правило — если вы беспокоитесь за свою психику, то ни в коем случае на запускайте викторину по Гарри Поттеру!