Я собираюсь подойти к этому из обсуждения на высоком уровне, а затем работать над вашими вопросами. В целях раскрытия информации у меня нет личного опыта использования socket.io, но я сталкиваюсь с проблемным пространством в отношении MMORPG.
Проектирование сетевой архитектуры движка MMORPG и / или выбор промежуточного программного обеспечения или проекта с открытым исходным кодом для обеспечения функциональности является одним из наиболее сложных решений, на которые влияют игровой дизайн, бюджет и технические знания команды. Окончательный выбор повлияет на другие архитектурные решения (а иногда и на дизайнерские решения).
Как разработчики MMORPG, мы планируем большой успех (часто также известный как катастрофический успех), когда большое количество людей запускает сигнальные огни и сирены. Одно из самых страшных больших чисел в алгоритмах, которые имеют N-квадрат (N ^ 2 в дальнейшем), в вашем вопросе первое, что бросилось мне в глаза, это то, что это звучало так, как будто проект призывал сущность передавать информацию все остальные связанные объекты. Это классический пример задачи N ^ 2.
ММО обычно подходят к решению проблем N ^ 2, атакуя проблему несколькими различными способами; системы осведомленности (ситуативные, пространственные и т. д.), в которых объект знает о некотором подмножестве всех других объектов, разделяя игроков на разные «осколки», разделяя игроков на «зоны» и / или создавая экземпляры, реализуя игровую механику, которая препятствует слишком большому игроки, собравшиеся вместе (штормы телепортации Ашерона Колла) и т. д.
Большинство MMORPG и многие FPS-движки имеют достаточно сложные сетевые архитектуры, которые поддерживают множество функций, включая:
- надежные и ненадежные каналы связи (TCP, пользовательские реализации надежных пакетов UDP и UDP)
- формирование полосы пропускания (расстановка приоритетов, время жизни и т. д.)
- автоматическая репликация полевых / доступных данных и вызовов функций
- атомарные наборы данных (т.е. данные, которые передаются вместе)
- дискретные обновления (т.е. где важен каждый переход)
- коррекция латентности
- различные приемы, чтобы клиент чувствовал себя отзывчивым
Я считаю , что документация Unreal Networking и Valve Networking документации обеспечивают хорошую грунтовку по целому ряду вопросов.
Итак, теперь давайте подойдем к вопросам.
Будет ли лучшей идеей «собирать» их и транслировать, скажем, раз в 1/10 секунды?
Здесь сложно дать простой ответ «да» или «нет» ... потому что это зависит от масштаба (количества наблюдающих объектов), частоты обновлений и размера обновлений. Например, собирать их все может быть ужасно неправильно, если размер обновлений может привести к потере буфера.
Клиент для MMORPG и игр FPS, как правило, разработан таким образом, что он визуализирует что-то, что «выглядит» правильно, даже если он не получает обновления для гораздо большего количества кадров обновления, чем это «нормально». При использовании ненадежной связи (UDP) вы можете просто ожидать потерять некоторое количество обновлений в пустоте, клиенты могут восполнить это, посылая более частые обновления, чем можно было бы использовать с надежным транспортом.
Из краткого обзора документации по socket.io видно, что он поддерживает как надежные, так и ненадежные (в своей терминологии изменчивые) пути связи.
Сначала я подхожу к этому, решая, с какой частотой нужны обновления ...
Если игрок движется по прямой линии с постоянной скоростью, более низкая частота обновления подходит, потому что наблюдающие клиенты могут с высокой точностью предсказать, где игрок будет находиться в любой момент времени. Когда игрок поворачивает по кругу или быстро меняет направление, требуется гораздо более частое обновление. И наоборот, когда игрок вообще не двигается, нет никакой причины отправлять обновления движения вообще.
Независимо от того, что, вероятно, нет необходимости (как правило) отправлять обновления каждый кадр от клиента на сервер. Сам сервер может по своему выбору отправлять сообщения в каждом кадре, где он есть, или задерживать их (см. Формирование полосы пропускания, расстановка приоритетов и время жизни обновления).
Другие типы обновлений имеют другие характеристики ... например, рассмотрим поле «здоровье», которое изменяется, когда игрок или существо получают повреждения. Один из способов реализовать это - транслировать каждое изменение немедленно, когда оно происходит, но это приводит к потере обработки и пропускной способности, если значение изменяется несколько раз в кадре или последовательных кадрах (сетевые архитектуры, которые реализуют формирование полосы пропускания, решают эту проблему путем объединения обновлений в только самые последние отправляются клиенту-наблюдателю, когда они имеют доступную пропускную способность).
должен ли клиент отправлять много разных сообщений (опыт получен, щелкнул по элементу), как только они появляются, или, скорее, только одно собранное?
Опять же, простой ответ «да» или «нет» не сработает. В зависимости от того, что именно вы подразумеваете под собранием ... оба могут быть правы при разных обстоятельствах, а также зависеть от реализации сетевого уровня.
Сбор сообщений для конкретной сущности для отправки одним сообщением может (в зависимости от реализации) уменьшить накладные расходы полосы пропускания при отправке сообщения (уменьшая ваши затраты) и наоборот (в зависимости от реализации, например сопоставления полей / значений, передаваемых строками), может увеличить пропускную способность требования по сравнению с более простым конкретным типом сообщения.
Изучая документацию по socket.io, мне кажется, что издержки сообщения находятся на верхнем уровне спектра, что благоприятствует сбору обновлений для отправки в виде сводного сообщения, а не множества отдельных обновлений.
Я бы порекомендовал просмотреть все обновления, которые вы планируете тиражировать, например, большинство MMORPG и FPS не заботятся о том, чтобы отправлять нажатые игроком события X наблюдателям, если это не приведет к изменению состояния объекта, о котором они также знали. ,