Jakie są zalety korzystania z systemu identyfikacji podmiotu?

12

Obecnie czytam książkę Programowanie gry AI według przykładu.

Książka wspomina o przypisywaniu unikalnych numerów ID każdemu bytowi w grze. Często, gdy jednostka A musi skontaktować się z jednostką B , A otrzymuje odwołanie do B , wysyłając numer identyfikacyjny B do klasy EntityDatabase . Ta klasa otrzymuje numery identyfikacyjne i zwraca odniesienia do encji.

Numery identyfikacyjne niektórych podmiotów można również pobrać z pliku zawierającego identyfikatory niektórych podmiotów (głównych bohaterów gry).

Moje pytanie brzmi: dlaczego miałbym to robić? Dlaczego nie mogę pracować bezpośrednio z referencjami? Czy czasami trudno jest uzyskać bezpośrednie odniesienie? Czy używanie systemu identyfikacji jest powszechnym podejściem? Czy są gry, które nie używają identyfikatorów?

Jestem nowy w tworzeniu gier. Proszę wyjaśnić zalety pracy z systemem identyfikacji podmiotów. Zalety i wady. Konkretne przykłady byłyby świetne. Dzięki

Aviv Cohn
źródło

Odpowiedzi:

18

Referencje sprawdzają się w wielu sytuacjach. Istnieją jednak trzy ważne sytuacje, w których odwołania nie działają dobrze:

  • Networking . Podczas wysyłania informacji o synchronizowaniu stanu podmiotów przez sieć nie można korzystać z odniesień. Musisz w jakiś sposób zidentyfikować byt, aby zdalne maszyny wiedziały, o kim mówisz.
  • Zapisywanie / ładowanie . Podczas zapisywania stanu gry na dysku odwołania do obiektów nie mogą z nim współpracować. Oznacza to, że gdy ładujesz stan, jednostka A, do której jednostka B została skierowana przez referencję, nie wie już, na kogo celować. Lokalizacje pamięci są różne, obiekty są różne.

  • Zarządzanie pamięcią . Posiadanie centralnego miejsca do przechowywania referencji oznacza, że ​​podczas usuwania encji nie trzeba przechodzić przez wszystkie swoje encje i usuwać referencje do niej, aby pamięć mogła zostać wyczyszczona. Referencje powinny być używane tylko wtedy, gdy są potrzebne, a następnie usuwane w dowolnym innym obiekcie. Zmniejszenie liczby referencji zapewnia, że ​​nie masz bytów zombie, do których odwołuje się tylko ostatnia rzecz, z którą wchodziły w interakcje lub jakaś inna istota. Pomaga to również uniknąć zerowych odwołań za pomocą znormalizowanego sposobu testowania, jeśli jednostka nadal istnieje.

MichaelHouse
źródło
2
ostatni akapit powinien być punktem wyjścia (zarządzanie pamięcią). Są sytuacje, w których jedna klasa potrzebuje odniesienia do innego bytu przez pewien czas, ale odwołanie do bytu może stać się nieprawidłowe (tj. Zmarł obiekt docelowy pocisku). Zwracając wartość NULL podczas żądania encji według identyfikatora, każda klasa bierze odpowiedzialność za wykonanie właściwej czynności (zamiast awarii), gdy odwołanie do encji stanie się nieprawidłowe.
LearnCocos2D
Dzięki za odpowiedź. Pytanie do wyjaśnienia. Ogólnie: w sytuacjach, w których jednostka A musi uzyskać odniesienie do jednostki B (aby ją zaatakować, wysłać do niej wiadomość, sprawdzić kolizję z nią lub z jakiegokolwiek innego powodu) - Czy powinienem użyć systemu identyfikacji w celu zdobyć, czy może czasem można uzyskać referencję bezpośrednio? Znaczenie: Czy jednostka A powinna zawsze otrzymywać odwołanie od EntityManager, wysyłając mu identyfikator podmiotu B (który odwołuje się do odniesień do encji i numerów identyfikacyjnych), a dopiero potem kontaktuje się z bytem B za pomocą odwołania z EntityManager? Czy powinienem zawsze korzystać z systemu identyfikacji?
Aviv Cohn,
A może czasem jest w porządku uzyskanie bezpośredniego odniesienia? Innymi słowy, kiedy należy encję A użyć EntityManager, aby uzyskać referencję przechowywaną w niej, a kiedy encja A może pobrać referencję do B za pomocą dowolnych środków?
Aviv Cohn,
Nie ma na to poprawnej odpowiedzi. Osobiście zaprojektowałbym system bytu tak, aby był niezależny od logiki gry. Oznaczałoby to, że logika gry nie ma nawet dostępu do bezpośrednich odniesień do encji. Zasadniczo unikałbym utrzymywania jakiegokolwiek odniesienia do bytu poza lokalnym zakresem obecnej metody. Oznacza to używanie EntityManager za każdym razem przed rozpoczęciem pracy na komponentach jednostki.
MichaelHouse
Widzę. Pozwól mi użyć przykładu, aby sprawdzić, czy rozumiem, co masz na myśli. Powiedzmy, że używam jednolitej siatki do wykrywania kolizji. Siatka to tablica 2d. Każda jednostka jest sprawdzana pod kątem kolizji tylko z jednostkami w tej samej „komórce” w siatce. Stosując podejście „zwykłe”, każda komórka zawierałaby odniesienia do obiektów GameEntity w obszarze, który reprezentuje. Stosując podejście „systemu identyfikacyjnego”, każda komórka zawierałaby numery identyfikacyjne podmiotów. Liczby te zostaną wysłane do EntityManager w celu otrzymania konkretnych odniesień w celu wykrycia kolizji. Czy to dobre zrozumienie?
Aviv Cohn
2

Ostatnią rzeczą jest to, że jeśli używasz wzorca puli obiektów, a byt zostanie zresetowany, ponieważ stworzenie umarło (na przykład) i odrodziło się gdzie indziej, odniesienie nadal będzie wskazywać na ten sam byt (błąd), a identyfikator nie będzie już pozostał ważny.

ID 5067 wskazuje na adres 0x8765 istota umiera, a inny spawnuje nowe stworzenie ID jest resetowane do 7073 Ktoś sprawdza ID 5067, wskazuje 0x8765, ale to stworzenie jest teraz zarejestrowane z ID 7073, więc baza danych ID jednostki wie, że użyłeś przestarzałego ID i informuje cię, że stworzenie, do którego próbowałeś dotrzeć, nie jest już aktywne.

To i wszystkie cudowne powody, o których wspomniał Byte56, to powód, dla którego dobrym pomysłem jest unikanie bezpośredniego korzystania z referencji.

AturSams
źródło