Як можна чітко присвоювати ідентифікатори юридичних осіб у мережевій грі?


17

Я працюю над системою сутності для мережевої гри і присвоюю кожному об'єкту унікальний 32-розрядний цілочисельний ідентифікатор, який я можу використовувати для серіалізації посилань на сутності та самі сутності.

В даний час я просто збільшую лічильник щоразу, коли створюється сутність. Я думаю, що ідентифікатори врешті-решт закінчуться, але я насправді не сподіваюся мати 4 мільярди осіб. Також це дозволяє уникнути проблеми, якщо об'єкт №5 знищений, і ми отримаємо ідентифікатор 5. Чи означає це посилатися на новий №5 або старий видалений №5?

Проблема полягає в тому, що я не впевнений, як впоратися / уникнути зіткнень. В даний час, якщо клієнт отримує оновлення для організації з ідентифікатором, більшим, ніж поточний "вільний ідентифікатор", він просто стикається з вільним ідентифікатором до попереднього. Але це не здається дуже надійним.

Я подумав, можливо, присвоїти діапазони кожному клієнту, щоб вони могли виділяти сутності без конфлікту (скажімо, верхні n біти - це номер гравця), але я переживаю, що станеться, якщо діапазони почали збігатися з часом.

Чи є кращий спосіб впоратися з цим? Чи варто мені навіть байдуже переповнювати ідентифікатори або проходити повз кінець дозволеного діапазону? Я можу додати код для виявлення цих випадків, але що б це зробило, якщо вони трапляються, крім краху.

Інший варіант - використовувати щось з більшими шансами на те, щоб бути унікальним, як 128-бітний GUID, але це здається дуже важким для гри, яка намагається мінімізувати мережевий трафік. Крім того, реально мені ніколи не знадобиться більше об'єктів одночасно, тоді я б вписався в 32-бітове або навіть 24-бітове ціле число.

Спасибі!


1
Чому всі клієнти не мають однакових організацій? Чи клієнти не синхронізовані? Або це великий світ чимось, де клієнти не всі працюють в одній грі.
Філіп

2
Моя архітектура поки що слабко відповідає UE3 (детальніше тут ). В основному клієнти знають лише про сутності, які знаходяться біля них у світі. Також клієнти не працюють у режимі блокування, але сервер контролює більшу частину логіки і може перезаписати клієнтські дані в будь-який час. Я думаю, зараз, коли я думаю про це, я міг би дозволити серверу створювати сутності та змушувати клієнтів використовувати RPC для цього. Я не впевнений у найкращому підході. Я графічний програміст по днях :)
Лукас

1
Я думаю, як ви кажете, ним слід керувати лише сервер, якщо це взагалі можливо у вашій заданій архітектурі. Потім збережіть стек безкоштовних ідентифікаторів сутності, який існує окремо до списку / карти сутностей, щоб ви знали, які ідентифікатори доступні. Якщо не виходить авторитетна модель сервера, то ваш діапазонний підхід повинен працювати нормально, з точки зору діапазонів. Чотири мільярди - це багато, навіть щоб розділити між 4000 гравцями в MMO. Потім використовуйте той же підхід, щоб відслідковувати доступні ідентифікатори, як і для автентичного. сервер.
Інженер

@Lucas, у вашому посиланні написано: "Сервер визначає набір" відповідних "Акторів для кожного клієнта". Це означає, що сервер знає про всі сутності та може їх перерахувати.
Килотан

1
Звичайно, але що робити, якщо клієнт створить нову сутність A, але перш ніж вона зможе отримати повідомлення про створення, сервер створює нову сутність B, їм обом присвоюється один і той же "вільний" ідентифікатор.
Лукас

Відповіді:


13

Що я зробив, це змусити сервер робити все . Клієнт може просто попросити сервер зробити щось, але нічого не може зробити сам. У цьому випадку сервер завжди буде тим, хто призначає ідентифікатори та вирішує проблему.

Я не займався прогнозуванням на стороні клієнта, поки чекав, коли сервер схвалить такі дії, як: "Стріляйте в ракету" або "Зробіть сонячну станцію тут". Ці дії хочуть створити об'єкти, а суб'єкти мають ідентифікатори. Поки я просто сиджу на великому пальці, чекаючи сервера, але я вважаю, що потрібно зробити, це створити тимчасову сутність, поки ви чекаєте затвердження сервера. Коли ви отримаєте схвалення сервера, сервер призначить ідентифікатор, і ви можете або оновити, або замінити тимчасовий об’єкт.

Я також не мав справу з переповненням ідентифікатора, але якщо сервер перебуває під повним контролем і він виявляє переповнення, він може робити все, що вам здається необхідним (перезапустити в 0, вибрати з вільного стека, збій тощо) і все клієнти навіть не знають і не дбають. Клієнти просто приймуть ідентифікатори, видані сервером.


Дякую за всі хороші інформаційні хлопці! Я закінчила роботу з сервером, який створює підходи до всіх об'єктів, але якщо я вважаю, що це вводить занадто велику затримку, я спробую метод Тревора.
Лукас

Для клієнтських ідентифікаторів (необхідних для прогнозування під час очікування сервера) ви можете просто використовувати префікс на id.
danijar

6

Коли я робив це для комерційної багатокористувацької гри, я зробив саме те, що ви пропонуєте: використовуйте 32-розрядне ціле GUID, де вісім біт - це номер гравця, а нижній двадцять чотири біти містять унікальне місцеве число.

Якщо / коли локальна кількість переповнюється (у моєму випадку, це майже ніколи не відбудеться; при нормальному використанні потрібно було б тривати тривалість безперервного відтворення в одному мережному сеансі протягом одного сеансу), власник надішле власник Повідомлення "Скидання всіх моїх об'єктів" та перенумеровування всіх існуючих об'єктів починаючи з нуля тому. У повідомленні було сказано всім одноліткам відмовитися від отриманих об'єктів та повторно запитувати їх.

Більш фантазійним підходом буде "Об'єкт з GUID" n "тепер" Object with GUID "m" "для кожного існуючого об'єкта. Але в моєму випадку це навряд чи справді відбудеться, і я не думав, що люди дійсно будуть проти віддалених об'єктів, що зникають із світу на півсекунди, через п’ять днів безперервної гри в одному сеансі мережі. ;)


Це гарна ідея для обробки переповнення. Просто, але я не думав про це :). "Забути" всіх ваших організацій приємно, оскільки в основному він може використовувати той самий кодовий шлях, який використовує клієнт, коли він приєднується до гри
Лукас,

4

Якщо ваші клієнти можуть нереститися своїми власними сутностями, я здогадуюсь, що у вас є багатокористувацька гра однолітків.

Якщо це так, ви, мабуть, не маєте занадто багато клієнтів. Звичайно, не більше 256. І ваш ідентифікатор сутності гарантовано вписується в 24 біти (16000000+ сутностей вистачає на всіх!). Отже, просто зробіть найвищий байт вашого ідентифікатора рівним ідентифікатору клієнта:

entityId = clientId<<24 + (maxEntityIn++)

або щось.

І якщо я помиляюся, і у вас є авторитетний сервер, просто ніколи не створюйте нових клієнтів для клієнтів.


1

Я використовую метод "найбільш наївний" (просто збільшуючи ціле число для кожного нового ідентифікатора) в своїй стійкій багатокористувацькій грі, і це працює чудово, оскільки я не даю клієнту створити новий ідентифікатор: s.

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

Як завжди, щоб запобігти обману , сервер повинен зробити ВСЕ створення та перевірку .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.