Pracuję nad systemem jednostek dla gry sieciowej i przypisuję każdej jednostce unikalny 32-bitowy identyfikator liczby całkowitej, którego mogę użyć do serializacji odniesień do jednostek i samych jednostek.
Obecnie tylko zwiększam licznik za każdym razem, gdy tworzony jest byt. Wydaje mi się, że identyfikatory ostatecznie się skończą, ale tak naprawdę nie spodziewam się posiadania 4 miliardów podmiotów. Pozwala to również uniknąć problemu, jeśli jednostka 5 zostanie zniszczona, a otrzymamy identyfikator 5. Czy ma to oznaczać odniesienie do nowego # 5 lub starego usuniętego # 5?
Problem polega na tym, że nie jestem pewien, jak radzić sobie z kolizjami / unikać ich. Obecnie, jeśli klient otrzyma aktualizację dla podmiotu o identyfikatorze wyższym niż jego obecny „darmowy identyfikator”, po prostu podbija swój darmowy identyfikator aż do przeszłości. Ale to nie wydaje się bardzo solidne.
Myślałem o przypisaniu zakresów każdemu klientowi, aby mogli oni alokować jednostki bez konfliktu (powiedzmy, że górne n bitów to liczba graczy), ale martwię się, co się stanie, jeśli zakresy zaczną się nakładać z czasem.
Czy istnieje lepszy sposób na poradzenie sobie z tym? Czy powinienem nawet przejmować się przepełnieniem identyfikatorów lub przekroczeniem dozwolonego zakresu? Mógłbym dodać kod, aby wykryć te przypadki, ale co by zrobił, gdyby zdarzyły się inaczej niż awaria.
Inną opcją jest użycie czegoś o większej szansie bycia wyjątkowym, takiego jak 128-bitowy identyfikator GUID, ale wydaje się to bardzo ciężkie w przypadku gry, która próbuje zminimalizować ruch w sieci. Ponadto, realistycznie, nigdy nie potrzebowałbym więcej jednostek naraz, wtedy zmieściłby się w 32-bitowej lub nawet 24-bitowej liczbie całkowitej.
Dzięki!
źródło
Odpowiedzi:
To, co zrobiłem, sprawia, że serwer robi wszystko . Klient (klienci) mogą po prostu poprosić serwer o zrobienie czegoś, ale sami nie mogą nic zrobić. W takim przypadku serwer zawsze będzie przypisywać identyfikatory i rozwiązać problem.
Nie miałem do czynienia z prognozami po stronie klienta, czekając, aż serwer zatwierdzi działania takie jak: „Wystrzel rakietę” lub „Zrób tutaj stację słoneczną”. Te akcje będą chciały tworzyć encje, a encje mają identyfikatory. Do tej pory po prostu siedzę na kciuku i czekam na serwer, ale uważam, że to, co należy zrobić, to utworzyć tymczasowy byt podczas oczekiwania na zatwierdzenie serwera. Po otrzymaniu zatwierdzenia serwera serwer przypisze identyfikator i możesz zaktualizować lub zastąpić obiekt tymczasowy.
Ja również nie miałem do czynienia z przepełnieniem identyfikatora, ale jeśli serwer ma pełną kontrolę i wykryje przepełnienie, może wykonać dowolną obsługę, którą uznasz za niezbędną (uruchom ponownie przy 0, wybierz z wolnego stosu, awarii itp.) I wszystkie klienci nawet nie będą wiedzieć ani się tym przejmować. Klienci akceptują tylko identyfikatory wręczone przez serwer.
źródło
Kiedy zrobiłem to w komercyjnej grze wieloosobowej, zrobiłem dokładnie to, co proponujesz: użyj 32-bitowej liczby całkowitej GUID, w której osiem górnych bitów to numer gracza, a dolne dwadzieścia cztery bity zawierają lokalnie unikalny numer.
Jeśli / kiedy nastąpi przepełnienie numeru lokalnego (w moim przypadku prawie nigdy by się to nie zdarzyło; przy normalnym użytkowaniu zajęłoby to od czterech do pięciu dni ciągłego odtwarzania w jednej sesji sieciowej, aby to się stało), właściciel wyśle Komunikat „Resetuj wszystkie moje obiekty” i przenumeruj wszystkie wciąż istniejące obiekty, zaczynając od zera. Wiadomość kazała wszystkim partnerom odrzucić otrzymane obiekty i ponownie zapytać o nie.
Bardziej wymyślnym podejściem byłby komunikat „Obiekt z GUID 'n' to teraz Obiekt z GUID 'm'” dla każdego istniejącego obiektu. Ale w moim przypadku było to mało prawdopodobne i nie sądziłem, że ludzie będą mieli coś przeciwko odległym obiektom znikającym ze świata na pół sekundy, po pięciu dniach nieprzerwanej gry w jednej sesji sieciowej. ;)
źródło
Jeśli Twoi klienci mogą odrodzić swoje własne istoty, domyślam się, że masz grę wieloosobową peer-to-peer.
W takim przypadku prawdopodobnie nie masz zbyt wielu klientów. Na pewno nie więcej niż 256. I gwarantujemy, że twój identyfikator podmiotu zmieści się w 24 bitach (16000000+ podmiotów wystarczy dla wszystkich!). Więc po prostu ustaw najwyższy bajt swojego identyfikatora na identyfikator klienta:
lub coś.
A jeśli się mylę i masz wiarygodny serwer, nigdy nie twórz nowych podmiotów na klientach.
źródło
Używam metody „najbardziej naiwnej” (po prostu zwiększam liczbę całkowitą dla każdego nowego ID) w mojej trwałej grze wieloosobowej i działa dobrze, ponieważ nie pozwalam klientowi tworzyć nowych ID: s.
Jeśli pozwolisz klientowi zdecydować (stosując wyjaśnienie techniki GUID), klient może również wprowadzić różne błędy, przypisując Stary identyfikator do nowego elementu (to właśnie wymyśliłem na głowie, myśląc, że to 5 sekund , może być wiele innych luk).
Jak zwykle, aby zapobiec oszukiwaniu , serwer powinien WSZYSTKO tworzyć i sprawdzać poprawność .
źródło