Ушел разбираться как устроен мультиплеер и взорвал себе мозг.
Ушёл писать быкенд для своего мультиплеера и внезапно понял, что у меня нет единой картины в голове. Как вообще шутер может работать без глюков, если между игроками есть пинг? Данные ведь передаются с задержкой. Я то думал что игрок просто будет всем рассылать свои действия и остальные будут получать их и как бы все. Работа сделана, мультиплеер готов. Но при таком раскладе игра становится дерганой.
Сидел разбирался, читал и меня в какой-то момент осенило. Оказывается, в мультиплеере нет одного настоящего времени. Есть сервер - это точка истины. Это единственная реальность где всё происходит по-настоящему. А у каждого игрока на экране - это некая запаздывающая проекция этой реальности, т.е. мы буквально видим мир с запаздыванием.
Вы можете сказать: "пффф, ну эт все знали". Но я вот как-то не задумывался об этом. Например, а зачем вообще в шутере стреляют на упреждение? Оказывается не только потому, что враг бежит. А потому что мы видим не текущее положение противника, а его прошлый кадр.
Так вот, сейчас расскажу подробнее. Когда игроки обмениваются данными, есть две фундаментальные проблемы:
1. достоверность данных и кто из игроков прав (а прав всегда читер 🙂).
2. Задержка, т.е. пинг.
Чтобы их решить приходится серверную часть делать точкой истины, которая всем рассылает справедливую и честную картину мира, одинаковую для всех. Но если всё считать только на сервере, появляется другая проблема - задержка управления.
И для решения проблемы задержки управления есть 2 механизма:
1. Локальная иллюзия настоящего. Когда мы нажимаем W, мы не отправляем серверу наши координаты. Мы отправляем что мы побежали, а сервер считает движение и шлет нам нашу позицию. Но чтобы при управлении не было лагов, клиент сразу рисует что мы побежали. А уже после ответа с сервера мы сверяемся с нашим истинным положением в пространстве, и если надо то пересчитываем наше положение и мягко его корректируем. И тогда управление чувствуется плавным.
Ок тут ясно, но а что с нашим положением у других игроков? Они не видят, что мы нажали какую то кнопку.
2. Мир живёт в прошлом. Дело в том, что сервер рассылает всем картину мира некими слепками с положением всех нужных объектов. И все игроки живут как бы в настоящем у себя, но мир вокруг они видят условно с прошлого слепка. Это сделано специально. Если бы мы пытались показывать самое последнее состояние, всё бы дёргалось и телепортировалось из-за скачков сети. А так получается что мы мягко отрисовываем весь мир от слепка к слепку.
Таким образом игра делается честной для всех и без рывков, да и в целом вся архитектура — это компромисс между честностью, плавностью и задержкой.
Все это слишком сложно для маленького фронтендера вроде меня. Где мои кнопочки, которым надо поменять цвет :) Если кто из знающих читает это, то может подскажите, правильно ли я понял данный механизм или чего-то упустил? Начну писать код сначала без всех этих штук. Просто чтобы каждый игрок получал свое положение и пусть будет все дергаться, иначе в башке все не уместить. И потом уже улучшать.
PS - вот сижу и думаю, ну а в DBD то чего маньяк с плохим пингом попадает по игроку если маньяк видит прошлое положение выжившего, а на самом деле выживший уже в другой позиции? Получается что в DBD разработчики отматывают положение выжившего и сверяют попадание в угоду маньяка, потому что если маньяк будет мазать из за лагов, то он с большей вероятностью ливнет, а он как бы один и игра закончится.