Раньше я немного программировал в игровой сети, но в основном с TCP для игр без необходимости в реальном времени. Я работаю над 2D Java-игрой с сетевым мультиплеером. Для обучения я хочу сделать это сам, без существующего сетевого API.
Как эффективно представить состояние игры, отправленное клиентам с сервера? Существует наиболее очевидный, но, вероятно, наименее эффективный способ, который заключается в создании какого-либо объекта контекста игрового состояния с указанием местоположения каждого игрока, состояния анимации и т. Д. И отправке его каждому игроку при каждом обновлении . Это не кажется ужасно сложным для реализации, но, вероятно, будет слишком большим для достижения чего-либо, близкого к взаимодействию в реальном времени (конечно, мой опыт с этим ограничен, поэтому я могу ошибаться)
Есть ли надежный способ, который вы использовали раньше, чтобы передавать только изменения состояния, и есть ли достаточно большой дисбаланс в производительности, который стоит дополнительной работы?
Ответы:
Регулярная передача полного состояния игры обычно неосуществима, хотя она сильно зависит от сложности вашей игры. Для простой игры с маленькой моделью мира это может сработать.
У меня лично был намного больший успех со следующей моделью:
Это обеспечило мне хорошую производительность даже с довольно большими игровыми мирами.
Еще один совет: пусть клиент позаботится об анимации, эффектах частиц и т. Д. Без ссылки на сервер. Нет смысла передавать их - они просто должны быть вызваны соответствующими игровыми событиями.
источник
Синхронизация обычно делится на две части: инкрементная и абсолютная.
Иногда вы должны передавать все, оно большое, но если вы упакуете его правильно, вы можете делать это раз в несколько секунд. Хорошо поставить все на место, исправляя ошибки постепенных обновлений.
Чтобы получить опыт в реальном времени, вы должны быстро передать некоторые изменения, но только те атрибуты, которые могут измениться. Например, если ракета летит по прямой линии, вам не нужно обновлять позицию, каждый клиент может рассчитать ее по начальной точке. Но когда он попадает, вы можете сгенерировать сообщение об этом, чтобы каждый клиент мог взорвать ракету в нужном месте. Незначительные глюки можно игнорировать.
Конечно, вы обновляете вещи только тогда, когда они могут повлиять на клиента! Что-то далеко от экрана не стоит. Некоторые значения могут обновляться реже. Например, позиции важны, чтобы быть более или менее точными, события (смерть, выстрелы, взрыв и т. Д.) Должны отправляться мгновенно, в то время как не важные значения могут иметь более низкие периоды обновления, например, табло, чат.
Упаковка данных также важна. Вы можете передать приблизительно 1400 байт (в зависимости от конфигурации, это значение по умолчанию) в одном пакете UDP, обычно есть несколько байтов заголовка. Таким образом, вы можете легко обновить 50-100 позиций в одной упаковке.
источник
В зависимости от вашей игры, вы можете рассмотреть модель «синхронного исполнения», в которой каждый клиент играет в одну и ту же игру, просто обмениваясь недетерминированными входами, такими как ввод с клавиатуры / джойстика и события таймера. (По сравнению с моделью, где каждый клиент выполняет локальное моделирование и рассчитывает интегрировать результаты удаленного моделирования). Ваш игровой движок обычно должен быть полностью детерминированным, чтобы это работало, что может быть тяжелым бременем в зависимости от игры. Но если игра уже детерминирована, это может быть проще.
В этом посте #AltDevBlogADay рассматриваются некоторые аспекты этого подхода в современной RTS (в частности, как определить, когда ваши клиенты начинают запускать «разные» игры).
Не забудьте сохранить это простым, пока не доказано обратное. :)
источник