Wydajność serwera FPS dla wielu graczy

12

Jest to związane z wydajnością MMO, z wyjątkiem tego, że pytanie dotyczy przepustowości. Chodzi o obciążenie procesora.

Złożyłem prosty FPS przy użyciu node.js i webGL. To bardzo proste, podobnie jak klon BuddyMaze w MIDI Maze. Niewiele się dzieje, wszyscy poruszają się w dwóch wymiarach (bez wysokości), strzelają prostymi pociskami i wbiegają w ściany.

W tej chwili, jeśli wykonam wiele połączeń z serwerem, gdzie każdy gracz strzela szybko podczas wirowania w kółko, mogę uzyskać około 15-20 graczy w grze, zanim serwer zmaksymalizuje rdzeń i zwolni. I dzieje się tak, gdy serwer pracuje z prędkością 30 klatek na sekundę. Przy 10 fps uzyskuję około 25-30 połączeń. Jest to dość złe, ponieważ gra będzie wkrótce miała znacznie więcej do zrobienia i będę musiał dopasować więcej graczy, aby było to wykonalne przedsięwzięcie.

Mój brat właśnie wskazał statystyki dotyczące serwera TF2 swojego współpracownika. Jego serwer ma niższą specyfikację niż nasza, ale działa na TF2, oczywiście o wiele bardziej złożonej grze, z ogromną prędkością 500 tyknięć na sekundę, z 36 użytkownikami na rdzeń. Ponadto obecnie zużywamy znacznie więcej przepustowości niż oni, ale nie próbowaliśmy jeszcze tak bardzo obniżyć.

Jak to jest możliwe? Jakie są sztuczki, aby zwiększyć wydajność serwera do tej wielkości? Niektóre rzeczy, o których wiem, to:

  • Obniżanie liczby klatek na sekundę na serwerze i interpolacja pozycji na kliencie. Mam pewną korzyść, ale najwyraźniej serwer TF2 nawet się tym nie przejmuje.
  • Robienie kosztownych rzeczy, takich jak wykrywanie kolizji na kliencie, i sprawdzanie go rzadko na serwerze. Jeszcze tego nie przeniosłem, dziś wieczorem. Mimo to nie oczekuję tak ogromnego zysku.
  • Podziel pole gry na regiony (drzewa quad), aby zminimalizować obliczenia. Nie miałem jeszcze na to okazji.
  • Rozważyłem niefortunną możliwość, że node.js jest po prostu dużo wolniejszy niż cokolwiek TF2 używa i może nie być odpowiedni do tego rodzaju zadań o wysokiej intensywności.
  • Czy to wszystko w magii konfiguracji serwera?

Więc jakie są inne sztuczki w branży, aby robić tylko minimum wymagane na serwerze, ale nadal mieć bezbłędną rozgrywkę? Istnieje duży konflikt między „odroczeniem do klienta, aby zaoszczędzić czas procesora” i „nie ufaj klientowi”, więc może to pomaga wiedzieć, gdzie linia jest rysowana w różnych sytuacjach?

Aktualizacja

Profilowanie jest naprawdę jedyną mantrą, jaką kiedykolwiek znalazłem, która jest absolutnie nieomylna. Szybko otoczyłem niektóre funkcje pomiaru czasu wokół mojego kodu (dzięki, FP!) I odkryłem, czego nigdy się nie spodziewałem: transmisja danych do kont klientów przez prawie cały czas wykonywania. W szczególności około 90%. Dalsze testy wykazały, że czas ten zależy zarówno od liczby klientów, jak i od wielkości danych, a tym bardziej od tych ostatnich. Przy obciążeniu 20 użytkowników skróciłem czas emisji o 90%, z 24 ms do nieco ponad 2 ms, wysyłając tylko „{}” zamiast pełnych danych. Ale tylko 5 użytkowników nadaje około 0,5 ms. Więc najwyraźniej muszę tutaj trochę zoptymalizować.

Pierwszą najbardziej oczywistą poprawą jest sprawdzenie linii wzroku. Zmniejszyłoby to zarówno liczbę osób, którym zależy na danych, jak i ilość danych wysyłanych do zainteresowanych stron. Czy mogę spróbować innych sztuczek w tej dziedzinie, które koncentrują się na zminimalizowaniu kosztów mojej operacji nadawania?

Tesserex
źródło
5
Profil kodu to naprawdę wszystko, co mogłem zasugerować. Domyślam się, że nie jest tak precyzyjnie dostrojony, jak myślisz, i dlatego TF2 działa z wyższą częstotliwością tykania na mniejszym sprzęcie. Myślę też, że TF2 może robić wszystkie rzeczy, które zasugerowałeś, i w rezultacie przyczynia się do tego, że ich wydajność jest wyższa.
Nate
1
Chcę usłyszeć twoje najnowsze wyniki. Czy udało Ci się uzyskać lepszą wydajność z node.js?
iddqd

Odpowiedzi:

5

Twój serwer nie powinien wysyłać stanu wszystkich graczy do wszystkich graczy przy każdym tyknięciu. Zamiast tego powinien wysyłać specjalnie spreparowany komunikat do każdego klienta, mówiąc co 500 ms, mówiąc: „X graczy w twoim porcie widoku powinno mieć te współrzędne w 500 ms”. W większości przypadków będzie to działać poprawnie, ale jeśli serwer zda sobie sprawę, że podał nieprawidłowe informacje, po prostu wysyła dodatkowy komunikat.

To znacznie zmniejszy ruch w sieci.

Inną rzeczą do rozważenia jest brak tykania gry na serwerze, ale zamiast tego klient musi wysyłać wiadomości tylko wtedy, gdy nastąpi akcja (zmiana kierunku, oddany strzał), a następnie obliczyć z wyprzedzeniem na serwerze, gdy akcja zostanie odebrana.

sorenbs
źródło
Tak, dodam teraz sprawdzanie linii wzroku. W rzeczywistości zyski były minimalne, od 45 ms dla 25 graczy, do 35 ms. Ale mogą wystąpić dodatkowe koszty związane z używaniem pojedynczych poleceń wysyłania zamiast rozgłaszania. I wysyłam wiadomości tylko na wejściu. Ale masz rację, może być sposób, aby wcale nie musieć tykać, tylko po otrzymaniu danych wejściowych.
Tesserex
1

Rozważyłem niefortunną możliwość, że node.js jest po prostu dużo wolniejszy niż cokolwiek TF2 używa i może nie być odpowiedni do tego rodzaju zadań o wysokiej intensywności.

To pewnie to. Serwer TF2 jest napisany przy użyciu C / C ++, a zatem będzie szybszy niż node.js (który, jeśli dobrze pamiętam, używa JavaScript interpretowanego w Javie)

Quake oparty na Google WebGL używa java dla serwera, a kod źródłowy znajduje się tutaj: http://code.google.com/p/quake2-gwt-port/ . Może warto to przejrzeć, aby zobaczyć, jak to się robi. Zastanawiam się także, co masz na myśli, mówiąc o szybkości klatek na serwerze. Nie ma powodu, aby renderować cokolwiek na serwerze, powinno ono po prostu być dostępne do przetwarzania poleceń wysyłanych przez klienta.

Wreszcie zasada „nie ufaj klientowi” jest ważniejsza niż przenoszenie kosztownych obliczeń na klienta w nadziei na poprawę wydajności. Szczególnie coś tak ważnego jak wykrywanie kolizji. Podwójnie, jeśli twoja gra jest oparta na Javascript, a więc dość łatwa do zhakowania (w porównaniu do czegoś takiego jak kompilowana wersja TF2).

Wiem, że to nie jest duża odpowiedź, ale mam nadzieję, że wskaże ci kilka kierunków, które mogą pomóc poprawić wydajność.

thedaian
źródło
7
Powinienem był powiedzieć częstość tykania zamiast częstości klatek. Oczywiście nic nie renderuje się na serwerze. Mam na myśli interwał, w którym przetwarza polecenia w pętli gry. Również kilka odpowiedzi sugeruje, że możesz dać klientowi takie funkcje, jak wykrywanie kolizji, o ile przeprowadzasz losowe weryfikacje co kilka sekund. Ktoś powiedział, że dość szybko eliminuje oszustów.
Tesserex