Многопользовательская игра с бэкендом JavaScript и frontend. Каковы лучшие практики?

Я думаю о создании веб-многопользовательской игры в Node.js. Это означает, что я буду использовать тот же язык в бэкенде и в frontend. Это было бы в в реальном времени и приблизительно 20 людях макс. в каждой 'комнате', таким образом, у меня есть несколько мыслей:

  1. Как я компенсирую задержку среди всех пользователей так, чтобы все видели то же самое то же время? Я думаю об отслеживании среднего времени ping каждого плеера, нахожу самый медленный и сообщаю другим клиентам времени (в миллисекундах), что они должны быть отложены каждый так, чтобы все максимально синхронизировались.

  2. Я думаю о выполнении игрового кода в бэкенде, а также в frontend (так как это - JavaScript на обоих концах), и просто имейте механизм коррекции ошибок для синхронизации с 'реальной игрой' в бэкенде. Тем путем игра должна работать гладко на frontend и только с немногими незначительными сбоями, когда синхронизация происходит. Также это минимизировало бы frontend JavaScript, взламывающий, так как мошенники будут синхронизироваться вниз с игрой бэкенда.

  3. Я должен получить действия плеера через сокет (нажатия клавиш), сообщить всем другим клиентам о действиях других игроков и в среднее время, 'играя' в игру в бэкенде и отправить информацию о синхронизации каждому из всего игрового состояния время от времени для синхронизации их?

Что Вы думаете? Есть ли больше материала, на который я должен рассмотреть или обратить внимание?

Отправьте любые мысли или ссылки на документацию или статьи относительно многопользовательских игр.


Править: Они полезны:

37
задан 5 revs, 2 users 89% 26 September 2011 в 19:21
поделиться

5 ответов

  1. Это очень трудно сделать, и я вижу много проблем с синхронизацией с "самым медленным". Можете ли вы ослабить это, чтобы клиенты могли быть "в конечном итоге согласованными"?

  2. Звучит неплохо.

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

1
ответ дан 27 November 2019 в 05:01
поделиться

1 - невозможно. Вы не знаете точно, сколько времени потребуется сообщению, чтобы прийти к клиенту, и ни одно измерение, которое вы сделаете, не будет обязательно применимо к следующему сообщению, которое вы отправите. Лучшее, что вы можете сделать, это приблизительное значение, но всегда нужно исходить из того, что люди будут видеть либо немного разные вещи, либо одни и те же вещи в немного разное время. Я бы рекомендовал просто посылать всем текущее состояние и использовать интерполяцию/экстраполяцию для сглаживания игрового процесса, так что все видят игру на несколько миллисекунд в прошлом, причем задержка варьируется как между игроками, так и во времени. В целом, это редко является большой проблемой. Если вы действительно хотите буферизировать некоторые прошлые состояния на сервере, вы можете интерполировать между ними и посылать разные старые данные разным людям в попытке синхронизировать то, что они видят, но в сочетании с симуляцией на стороне клиента и дрожанием времени передачи вы все равно увидите некоторые различия между машинами.

2 - типичный способ - запустить симуляцию на сервере и регулярно посылать (небольшие) обновления состояния клиентам. Клиенты обычно запускают свои собственные симуляции и имеют возможность смешивать свое собственное предсказанное/интерполированное состояние с авторитетным состоянием, которое посылает им сервер. Все решения, кроме пользовательского ввода, должны приниматься на стороне сервера. В конечном счете, способ смешивания - это просто компромисс между гладким внешним видом и точным состоянием, так что это косметическое решение, которое вам придется принять.

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

27
ответ дан 27 November 2019 в 05:01
поделиться

Я не буду прямо касаться ваших вопросов, потому что другие ответы подходят лучше всего. Но я предлагаю изучить HTML5, WebSockets и Comet, которые обещают значительно улучшить производительность в реальном времени. Эти технологии позволяют иметь длительные HTTP-запросы, позволяя серверу передавать данные клиенту, а не опрашивать сервер. Это может существенно ускорить процесс.

Вот некоторые ресурсы, которые могут оказаться полезными:

5
ответ дан 27 November 2019 в 05:01
поделиться

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

Обычно клиент прогнозирует, как идут дела на короткое время, а затем исправляет обновление с сервера. Вы также можете внести поправки во время. Например, если сервер сообщает вам, что «игрок 2 находится в точке P, движется со скоростью V», вы можете попытаться узнать, сколько лет этому сообщению, основываясь на недавнем эхо-запросе, и исправить положение из P к P + x * D .

0
ответ дан 27 November 2019 в 05:01
поделиться

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

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

1
ответ дан 27 November 2019 в 05:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: