Autor Wątek: NPC WORLD  (Przeczytany 2981 razy)

Offline arteer

  • Użytkownik

# Sierpień 11, 2014, 23:53:22
Witam wszystkich.

Od dłuższego czasu pracuje nad plikami sieciowymi. Posiadam wszystko od logowania z bazy po spawny postaci w sieci itp. Zastanawiam się tylko nad jedną rzeczą, która mnie intryguje od dłuższego czasu...

Wyobraźmy sobie sytuację, że mamy 4000 NPC na serverze (trzymam je w liście). Logujący się gracz musi otrzymać informacje o pozycjach NPC, ich aktywnych czynnościach etc.

Oczywiście wysyłanie wszystkich danych do gracza odpada bo nie potrzebujemy informacji czy na innej mapce NPC się poruszają czy nie. I tutaj pada moje pytanie:

W jaki sposób, żeby było optymalnie mogę przeglądnąć kolekcję 4000 NPC i wybrać z pośród nich te najbliżej mnie?
Czy przeszukiwanie tablic,list,słowników? A może HashSet?
Weźmy pod uwagę, że jak jednocześnie zalogowałoby się 1000 osób, to server przemagluje kolekcję 4000 x 1000 = 4mln razy w jednej chwili.

EDIT:
Jeżeli chodzi o język programuję w C#.


« Ostatnia zmiana: Sierpień 11, 2014, 23:55:02 wysłana przez arteer »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Sierpień 12, 2014, 00:01:18
dzielisz mape na sektory i przy poruszaniu przerejestrowujesz npc jak i graczy miedzy sektorami. stad bliski skok masz do quadtree, ktore pozwoli Ci przyspieszyc przeszukiwanie mapy i listowanie jednostek w zasiegu.

Offline arteer

  • Użytkownik

# Sierpień 12, 2014, 00:30:55
Czyli im mniejsze sektory tym lepiej bo mniejsze listy NPC do indeksowania?

Offline Karol

  • Użytkownik

# Sierpień 12, 2014, 00:45:08
Z punktu wydajności większe sektory są lepsze, bo możesz szybciej odrzucać większe połacie terenu, jednakże z punktu gracza to mniej fajne, bo jak przekroczy granicę to znikną moby za nim, a pojawią się przed nim. Trzeba znaleźć złoty środek. Natomiast im mniejsze sektory to tym bardziej zbliżasz się do bycia w ogóle bez sektorów.

Offline Xirdus

  • Redaktor

# Sierpień 12, 2014, 00:52:16
Przede wszystkim sektor powinien być na tyle duży że widać teren dookoła. I gracz dostaje informację na temat sektora w którym się znajduje i wszystkich naokoło - tak żeby było płynne przejście.

Offline arteer

  • Użytkownik

# Sierpień 12, 2014, 09:57:32
To raczej jestem na dobrej drodze bo u mnie sytuacja wygląda w ten sposób:

Do projektu wykorzystuje silnik Unity3D i za pomocą metody:http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html

Sprawdzam wszystkie NPC w okół danego gracza. Przykładowo:
Gracz się loguje -> OverlapSphere (po stronie servera) sprawdza jakie NPC znajdują się w okół gracza po czym informacje na temat tych np 10 NPC wędrują do clienta (tam wykonuje się spawn i ruch jeżeli są w trakcie ruchu do jakiejś pozycji). Oczywiście wysyłam wszystko w jednym pakiecie, i dzięki temu nie muszę maglować listy z NPC.

Tylko problem zaczyna się w momencie kiedy biegne... Wyobraźcie sobie grę typu diablo 2. Wbiegamy z pustego miejsca na np cmentarz gdzie jest 100NPC. I teraz mam problem z tym, że w momencie kiedy zakres złapie pierwszego NPC z brzegu -> już wysyła pakiet o nim. Nie wiem w jaki sposób rozegrać to tak, żeby w 1 pakiecie wysłało wszystkie moby. Jeżeli dajmy na to odczekam chwilę zbiorę je wszystkie do kupy i dopiero wyślę to te do których już podbiegłem po prostu pojawią się w jednym czasie. A chcę, żeby w trakcie gdy biegnę postacie już zza ekranu były zespawnione na swoich miejscach gdy sięgam ich zakresem.

Owszem to wszystko działa jeżeli na ekranie mamy do 10 NPC. Ale jak poustawiałem powyżej 40 to 1 mob = 1 pakiet (jak go zlapie w zasiegu) a dobrze by było jakimś cudem 1 pakiet danych przeznaczyć np na 10 mobów naraz. Nie wiem czy rozumiecie o co mi chodzi? Ciężko to wytłumaczyć. Do wszystkiego używam Lidgren.Network

Offline Amun

  • Użytkownik

# Sierpień 12, 2014, 12:37:31
Możesz spróbować ustawić sobie pewne punkty w grze, po których przekroczeniu będzie wiadomo, że jest tam ileś mobów i je wysłać.. Jeżeli to świat zamknięty(jak we wspomnianym przykładzie z Diablo), to powinno działać. Znowu, kiedy to świat otwarty, to w zasadzie nigdzie nie zdarza się żeby był spawn 100 mobów w jednym miejscu... wyjątkami są specjalne lokacje, jak miasta i dungeony czy inne takie, w których z góry wiadomo, że jest tam tego pełno.

Offline arteer

  • Użytkownik

# Sierpień 12, 2014, 12:47:59
Dobra dzięki wszystkim. Myślę, że jakoś sobie poradzę powolutku wszystko testując:)

Offline FrozenShade

  • Użytkownik
    • Skullstone's official site

# Sierpień 13, 2014, 02:20:11
Z punktu wydajności większe sektory są lepsze, bo możesz szybciej odrzucać większe połacie terenu, jednakże z punktu gracza to mniej fajne, bo jak przekroczy granicę to znikną moby za nim, a pojawią się przed nim. Trzeba znaleźć złoty środek. Natomiast im mniejsze sektory to tym bardziej zbliżasz się do bycia w ogóle bez sektorów.

A może wersja z małymi sektorami, ale sprawdzamy sektor, w ktorym znajduje sie gracz + sektory sąsiednie? Pozbywamy sie w ten sposób brzydkiego efektu przejścia pomiędzy sektorami, gdzie nagle pojawiają się moby/npc.

Można to dodatkowo rozwinąć o coś w rodzaju otoczenia gracza. Przegląd sektorów nie odbywał by się z każdym krokiem, ale co pewną deltę. W otoczeniu gracza znajdowały by się moby/npc które są troche dalej od niego, niż powiedzmy zasięg wzroku. Taką listę (tego co widzimy + troche dalej) można by z powodzeniem wysyłac do klienta i to tam podejmowana była by decyzja co ostatecznie wyświetlić, po stronie serwera mieli byśmy za to dużo rzadsze przeglądanie listy. Moby (bo npc stoja w miejscu) poruszając się (np goniąc innego gracza) badały by swoje otoczenie w poszukiwaniu innych graczy i ewentualnie dodawały by sie do 'otoczenia' danego gracza.

Polecam analizę istniejących rozwiązań, np jakiegoś opensource'owego serwera Lineage 2.
« Ostatnia zmiana: Sierpień 13, 2014, 02:27:36 wysłana przez FrozenShade »