Jak radzą sobie z nimi gry takie jak Minecraft, a właściwie każda gra MMO z przetwornikami?
Powiedzmy, że teren odradza 3 krople „brudu” za każdym razem, gdy kopiesz wspomniany teren. Powiedzmy, że każdy element ma animację obrotu obliczoną dla każdej klatki. Jeśli liczba odbiorników na świecie będzie bardzo wysoka, byłby to bezużyteczny, ogromny narzut w obliczeniach ramek dla klienta na danym serwerze, ponieważ jest prawdopodobne, że wiele z tych przedmiotów znajduje się o wiele lat świetlnych od Ciebie.
Pomyślałem więc, że musisz „robić rzeczy” tylko przy przetwornikach zbliżonych do lokalnego odtwarzacza, ale nadal oznacza to, że każda klatka muszę sprawdzać, czy jakikolwiek inny przedmiot jest wystarczająco blisko, aby zaczął się animować.
Moje aktualne pytanie brzmi: w jaki sposób inne MMO rozwiązały ten problem?
źródło
minecraft:dirt
) i liczba (30), więc gdy gracz jest wystarczająco blisko, aby go podnieść, wystarczy dodać jak najwięcej z ekwipunku gracza. Jeśli gracz ma tylko miejsce na 6 przedmiotów, a stos 30 leży na ziemi, gracz podniesie 6, a stos na ziemi zmniejszy się do 24.Odpowiedzi:
Po prostu ładując tylko te części świata, które znajdują się blisko gracza. Wszystko inne jest zawieszone na dysku twardym. Kiedy w odległości około dwóch kilometrów leży niewielki obiekt, gracz nie może go zobaczyć i nie może z nim współdziałać. Nie ma więc powodu, aby go aktualizować lub wysyłać do GPU w celu renderowania. Im mniejszy obiekt i jego zakres interakcji, tym niższy zasięg wokół odtwarzacza, w którym należy go załadować.
Odnalezienie tego, co jest blisko gracza: sprowadza się to głównie do przechowywania świata w strukturze danych zoptymalizowanej pod kątem wyszukiwania przestrzennego. Dobrymi kandydatami do nich są hasze przestrzenne i wielowymiarowe drzewa .
źródło
Masz dwie bardzo różne rzeczy do zarządzania:
Serwer musi zarządzać całym światem w autorytatywny sposób. W tym celu konieczna jest komunikacja z N klientami (gdzie N jest „masywny”).
Klient mógł w zasadzie wiedzieć o całym świecie, ale nie musi . Dla klienta wystarczy wiedzieć o tym, co znajduje się w pobliżu gracza. Zakładając na przykład dość zgrubne podziałanie podobne do siatki, musiałby znać tylko komórkę gracza i 26 komórek wokół odtwarzacza (lub 8 komórek, jeśli masz siatkę 2D). Lepsza jest nieco drobniejsza siatka, ale masz pomysł.
Teraz dużo przetworników, co to jest „dużo”? Kopiesz może 5 rzeczy na sekundę, to może dwa tuziny liczb, które muszą zostać zaktualizowane na serwerze, a serwer może być zmuszony przekazać je innemu graczowi, którego obszar zainteresowania pokrywa się z twoją komórką. W przypadku komputera jest to dość absurdalna ilość danych i nieistotna ilość obliczeń. Może stać się wyzwaniem, gdy w tej samej komórce znajdują się setki / tysiące graczy (wtedy twoje parowanie jest zbyt szorstkie).
Serwer nie musi wiedzieć ani przejmować się obrotami przetworników ani takimi szczegółami. Dlaczego miałoby to
Klient tak naprawdę nie przejmuje się tym, ponieważ jest to po prostu oko, które klient może nadrobić w locie.
Z punktu widzenia serwera niezbędna jest wiedza, że kopałeś (30, 40, 50) w węźle, w którym się znajdujesz, i decyduje, że spawnuje to np. Trzy obiekty typu 5 lub jeden obiekt typu 7 z liczba 3. To wszystko, na czym mi zależy i to wszystko, co ci mówi. Będzie również zawierać tę informację w danych wysyłanych do kogoś, kto później przesunie swój obszar zainteresowania nad komórką siatki (zakładając, że do tego czasu nadal tam jest).
Klient zostaje poinformowany o pojawieniu się tam trzech obiektów, bla bla. Teraz, niezależnie od tego, czy klient wyświetla mapę ASCII-art, na której jest teraz „D”, czy pokazuje wirującą kupę brudu, wszystko jest takie samo. Niezależnie od tego, czy stosy mają różne obroty, czy tylko te znajdujące się w pobliżu gracza obracają się tak samo. To tylko rzeczy wyświetlane na monitorze, nie mają wpływu na nikogo innego.
Tak więc w konkretnym przypadku, w którym chcesz obracać tylko stosy brudu w pobliżu, możesz po prostu sprawdzić zasięg wszystkich znanych ci obiektów. Ponieważ zestaw danych nie jest duży, nawet brutalna siła na wszystko będzie działać.
Możesz (i powinieneś) w zależności od rozmiaru partycjonowania, trywialnie przyciąć komórki siatki, które są zbyt daleko.
Możesz oczywiście dalej dzielić komórkę na partycje i używać czegoś super inteligentnego. Jeśli chcesz, użyj drzewa kd, ale nie spodziewaj się wielkich zysków. Możesz przycinać rzeczy na Manhattanie lub sortować swoje rzeczy na małej siatce ... ale dlaczego?
Kontrola odległości (naprawdę do kwadratu odległość, ale jest taka sama dla ciebie) to tylko dwa mnożenia i dodatek (zoptymalizowany do MUL, MADD, więc tak naprawdę tylko dwie operacje), po którym następuje ruch rozgałęzienia lub warunkowy. Jest to prawie tak szybkie, jak każda inna operacja, która nie przycina jednocześnie całych komórek siatki. W rzeczywistości jest to coś, co można nawet zrobić na GPU ...
Widząc, jak będziesz mieć kilkaset lub co najwyżej kilka tysięcy kontroli odległości względem tej samej pozycji (odległość kwadratowa działa dobrze), naprawdę nie masz problemów z wykonaniem tych obliczeń, tym bardziej, że jest to raczej pamięć podręczna - przyjazna iteracja nad ciągłą pamięcią, a przy ruchach warunkowych jest tanio brudna. Coś jak (pseudokod)
rot = r[i] + 1; r[i] = ((dx*dx+dy*dy) < DIST_SQ) ? rot : r[i];
. To jedna iteracja na tablicy kilkuset wartości na ramkę. Komputer nie mógł się tym mniej przejmować, to ciągłe ładunki i sklepy, prosta ALU, żadnych oddziałów i tylko kilka tysięcy iteracji.To (wiele do jednego) nie jest tą samą klasą problemu (wiele do wielu) jak na serwerze. Naprawdę klient nie jest problemem.
źródło
@ T.Sar pisze w komentarzu, że powinieneś przyjrzeć się koncepcji „załadowanej porcji” Minecrafta, aby uzyskać więcej informacji. Jeśli tak, pamiętaj, że jest to dość skomplikowane w Minecraft, ponieważ ludzie budują maszyny w grze.
Oto bardzo uproszczona wersja:
Świat jest podzielony na kwadratowe regiony (fragmenty). W Minecraft istnieje również podział wysokości, ale większość MMO tego nie potrzebuje.
Klient gry dba tylko o regiony blisko gracza. Jest to o wiele prostsze niż narysowanie koła wokół gracza, ale wystarczająco dobre.
W Minecraft regiony to 16 x 16 bloków, a klient wie o 9 x 9 regionów, 4 regiony w każdym kierunku. (4 regiony na wschód + region gracz znajduje się w + 4 regionach na zachód = łącznie 9 regionów. Ta sama północ / południe)
W tych liczbach nie ma nic magicznego, używaj tego, co ma sens w grze.
Klient animuje tylko rzeczy w tym obszarze. Serwer oblicza rzeczy takie jak wędrujące potwory tylko w regionach zbliżonych do niektórych graczy.
Kiedy gracz chodzi po regionie, nic szczególnego się nie dzieje, kiedy przekracza granicę regionu, „krawędź animacji” zostaje przesunięta o jeden region. Następnie klient musi zapytać serwer o regiony, które teraz widzi.
Nie ma nic złego w posiadaniu kilku zagnieżdżonych limitów animacji. Np. Animowany przedmiot spada na obszar 3x3, wędrując potwory na obszarze 5x5 i po prostu pokazuje krajobraz w obszarze 9x9.
Serwer przechowuje „zamrożoną wersję” regionów, których żaden gracz nie widzi. Jeśli zajmuje to dużo pamięci, możesz po pewnym czasie je rozładować. Kiedy gracz przyjedzie, region zostanie ponownie załadowany bez upuszczenia przedmiotu. Następnym razem musisz być szybszy, Gracz 1.
źródło