Хотел сделать крутую онлайн игру. Расскажу где всё пошло не так
Идея была простая до безобразия. Браузерная змейка но с живыми соперниками. Canvas, websocket, Node.js. Всё это я более-менее знал, казалось делов на пару выходных.
Первый день вообще огонь. Змейка ползает, еду ест, растёт, цвета красивые. Думаю ну всё, осталось только игроков подключить.
Ага.
Синхронизация это ад
Подключил websocket, запустил два браузера на одной машине, вроде видят друг друга. Отлично. Добавил искусственную задержку 50мс чтобы проверить как будет на реальной сети.
Всё сломалось.
У одного игрока змейка уже повернула, у второго она ещё летит прямо. Столкновения каждый клиент считает сам по своей картинке мира. Один видит что убил соперника, второй видит что убил он. Оба правы по своей логике.
Полез гуглить. Нашёл что это называется authoritative server, client-side prediction, lag compensation. Понял что я вообще не туда смотрел когда проектировал. Думал займёт вечер. Потратил месяц и всё равно сделал через одно место.
Лобби которое я не планировал
Ок, физику перенёс на сервер. Теперь надо чтобы игроки могли найти друг друга, подождать, начать игру. Звучит как мелочь.
Это не мелочь.
Ожидание, старт, игра, конец, переиграть — каждое состояние надо синхронизировать. И самое весёлое это когда один игрок просто закрыл вкладку в середине партии. Что показывать второму? Кто победил? Как засчитать? Три вечера только на обработку разрывов соединения.
Читер за пять минут
Дал поиграть другу. Через пять минут он открыл консоль и начал отправлять серверу произвольные координаты. Змейка телепортировалась куда хочет. Я вообще не думал об этом когда писал архитектуру.
Что по итогу
Игра работает. Можно найти соперника и сыграть партию. Но код это такой клубок что я боюсь его открывать.
Главное что понял: онлайн игра это не игра плюс немного сетевого кода. Это совсем другая задача где сеть и есть основная сложность. Я недооценил это раз в десять минимум.
Код выложу на GitHub как разберу этот клубок. Пока стыдно показывать.
Кто делал нормальный мультиплеер в браузере, как решали синхронизацию? Потому что мои костыли мне самому не нравятся.