Я работаю над системой сущностей для сетевой игры и назначаю каждой сущности уникальный 32-битный целочисленный идентификатор, который я могу использовать для сериализации ссылок на сущности и сами сущности.
В настоящее время я просто увеличиваю счетчик каждый раз, когда создается объект. Я предполагаю, что идентификаторы со временем закончатся, но я не ожидаю, что у меня будет 4 миллиарда сущностей. Также это позволяет избежать проблемы, если сущность № 5 уничтожена, и мы получаем идентификатор 5. Это означает, что он ссылается на новый № 5 или старый удаленный № 5?
Проблема в том, что я не уверен, как справиться / избежать столкновений. В настоящее время, если клиент получает обновление для объекта с идентификатором выше, чем его текущий «свободный идентификатор», он просто увеличивает свой свободный идентификатор до этого. Но это не кажется очень надежным.
Я подумал о том, чтобы, возможно, назначить диапазоны каждому клиенту, чтобы они могли распределять сущности без конфликта (скажем, верхние n битов - номер игрока), но меня беспокоит, что произойдет, если диапазоны со временем начнут перекрываться.
Есть ли лучший способ справиться с этим? Должен ли я вообще беспокоиться о переполнении идентификаторов или выходе за пределы допустимого диапазона? Я мог бы добавить код для обнаружения этих случаев, но что бы он сделал, если бы они произошли, кроме аварии.
Другой вариант - использовать что-то с большей вероятностью быть уникальным, например, 128-битный GUID, но это кажется очень тяжелым для игры, которая пытается минимизировать сетевой трафик. Кроме того, реально мне никогда не понадобилось бы больше сущностей за один раз, чем поместилось бы в 32-битное или даже 24-битное целое число.
Благодарность!
источник
Ответы:
Что я сделал, так это заставил сервер делать все . Клиент (ы) может просто попросить сервер сделать что-то, но не может ничего сделать сам. В этом случае сервер всегда будет тем, кто назначит идентификаторы и проблема решена.
Я не имел дела с предсказаниями на стороне клиента, пока сервер ждал одобрения таких действий, как «Стреляй в ракету» или «Сделай солнечную станцию здесь». Эти действия захотят создать сущности, а сущности имеют идентификаторы. До сих пор я просто сижу на большом пальце в ожидании сервера, но я верю, что нужно создать временную сущность, пока вы ждете одобрения сервера. Когда вы получите одобрение сервера, сервер назначит идентификатор, и вы можете обновить или перезаписать временный объект.
Я также не имел дело с переполнением идентификатора, но если сервер находится под полным контролем и обнаруживает переполнение, он может делать любую обработку, которую вы считаете необходимой (перезапуск с 0, выбор из свободного стека, сбой и т. Д.) И все клиенты даже не будут знать или заботиться. Клиенты просто принимают идентификаторы, выданные сервером.
источник
Когда я сделал это для коммерческой многопользовательской игры, я сделал именно то, что вы предлагаете: использовать 32-разрядное целое число GUID, где верхние восемь бит - это номер игрока, а нижние двадцать четыре бита содержат локально уникальный номер.
Если / когда локальный номер переполнится (в моем случае это почти никогда не произойдет; при нормальном использовании для его выполнения потребовалось бы четыре-пять дней непрерывного воспроизведения в одном сетевом сеансе), владелец отправит Сообщение «Сброс всех моих объектов» и перенумерация всех еще существующих объектов, начиная с нуля назад. В сообщении всем сверстникам было отказано в получении объектов, которые они получили, и запросить их снова.
Более причудливым подходом было бы сообщение «Объект с GUID« n »- теперь объект с GUID« m »» для каждого существующего объекта. Но в моем случае это вряд ли когда-либо могло произойти, и я не думал, что люди действительно будут возражать против удаленных объектов, исчезающих из мира на полсекунды, после пяти дней непрерывной игры в одной сетевой сессии. ;)
источник
Если ваши клиенты могут порождать свои собственные сущности, я полагаю, у вас есть одноранговая многопользовательская игра.
Если это так, у вас, вероятно, не слишком много клиентов. Конечно, не более 256. И идентификатор вашей сущности гарантированно умещается в 24 бита (16000000+ сущностей достаточно для всех!). Итак, просто сделайте старший байт вашего идентификатора равным идентификатору клиента:
или что-то.
И если я ошибаюсь и у вас есть авторитетный сервер, просто никогда не создавайте новые сущности на клиентах.
источник
Я использую «самый наивный» метод (просто увеличиваю целое число для каждого нового идентификатора) в моей постоянной многопользовательской игре, и он отлично работает, потому что я не позволяю клиенту создавать новые идентификаторы: s.
Если вы позволите клиенту принять решение (используя объясненную технику GUID), он также может внести различные ошибки, назначив старый идентификатор новому элементу (это то, о чем я думал в течение 5 секунд, думая, что это 5 секунд). может быть множество других лазеек).
Как обычно, чтобы предотвратить мошенничество , сервер должен ВСЕ создавать и проверять .
источник