Zeetius
ПРОДУКТЫ

Турнир KBSA транслируется на Zeetius TV СМОТРЕТЬ

Разработка

Настольный теннис, борьба, баскетбол: один движок для трёх совершенно разных видов спорта

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

7 минут чтения

Три интерфейса подсчёта очков рядом: настольный теннис, борьба и баскетбол

Мы писали о парадигмах подсчёта очков в общих чертах. Эта статья — конкретная версия: три вида спорта, которые мы действительно обслуживаем, чего требует каждый и где заканчивается общий движок и начинается работа под конкретный спорт.

Настольный теннис: розыгрышный вид спорта с проблемой ротации

Подсчёт выглядит просто. До трёх или четырёх побед, партии до 11, разница в два очка, без потолка. Вся сложность — в подаче.

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

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

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

Интерфейс подсчёта в настольном теннисе с выделенным производным индикатором подачи и ротацией в парах

Производное состояние лучше введённого

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

Борьба: непрерывные баллы и внезапное завершение

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

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

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

Баскетбол: сложность в часах

Арифметика баскетбола — самая простая из трёх: два, три или одно очко, приписанное игроку и команде. Сложными её делают часы.

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

Партии и розыгрыши настольный теннис, бадминтон, теннис, пиклбол, падел, волейбол
Единоборства борьба, шахбокс
Игровое время баскетбол, футбол, гандбол, хоккей

Что действительно общее

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

  • Поток событий: упорядоченный, только с добавлением, устойчивый к потере связи, воспроизводимый. Одинаковый для всех трёх.
  • Повторное проигрывание на сервере как источник истины, чтобы исправления везде работали одинаково.
  • Рассылка на лайв-страницы, сетки, оверлеи трансляций и аналитику — единый путь публикации.
  • Структура турнира: жеребьёвки, сетки, расписание, результаты и рейтинги, которым не важно, в каком виде спорта получен результат.
  • Офлайн-очередь и сверка, написанные один раз и унаследованные каждым видом спорта.

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