Jak napisać grę sieciową? [Zamknięte]

73

Na podstawie Dlaczego tak trudno jest stworzyć MMO? :

Tworzenie gier sieciowych nie jest trywialne; do pokonania są nie tylko duże opóźnienia, ale także zapobieganie oszustwom, zarządzanie stanem i równoważenie obciążenia. Jeśli nie masz doświadczenia w pisaniu gry w sieci, będzie to trudne zadanie edukacyjne.

Znam teorię na temat gniazd, serwerów, klientów, protokołów, połączeń i tym podobnych.

Teraz zastanawiam się, jak nauczyć się pisać grę sieciową:

  • Jak zrównoważyć problemy z obciążeniem?
  • Jak zarządzać stanem gry?
  • Jak zachować synchronizację?
  • Jak chronić komunikację i klienta przed inżynierią wsteczną?
  • Jak obejść problemy z opóźnieniami?
  • Które rzeczy powinny być obliczane lokalnie, a które na serwerze?
  • ...

Czy są jakieś dobre książki, samouczki, witryny, ciekawe artykuły lub inne pytania na ten temat?

Szukam szerokich odpowiedzi, ale konkretne też są w porządku, aby poznać różnicę.

Tamara Wijsman
źródło
4
Tak, są książki, samouczki, strony, ciekawe artykuły i inne pytania dotyczące tego.
Ricket
2
Dodałem nagrodę, aby przeforsować pytanie bez modyfikacji i dać użytkownikom powód odpowiedzi, ponieważ to pytanie zasługuje na odpowiedzi, dzięki czemu najlepszy odpowiadający otrzymuje reputację za swoją pracę, ale nie ma ani jednej odpowiedzi, która odpowiedziałaby na pytanie.
Tamara Wijsman

Odpowiedzi:

61

Oprócz artykułu z linkami w innych odpowiedziach, mogę trochę opowiedzieć o doświadczeniu projektu Arianne .

Jak zachować synchronizację?

Stworzyliśmy platformę „ Marauroa ” wokół koncepcji akcji i percepcji: Akcje są wysyłane od klienta do serwera z danymi wejściowymi użytkownika takimi jak (chodź w lewo, atakuj potwory # 47, powiedz „cześć”). Opinie są przesyłane z serwera do klientów, informując ich o stanie świata, który ich otacza. Te opinie są wysyłane co turę. W zależności od gry stosujemy czasy tury od 30 do 300 ms.

Mamy dwa rodzaje percepcji : Pełna percepcja jest wysyłana przy logowaniu i po wejściu gracza do nowego obszaru (strefy). Następnie wysyłane są odmienne percepcje obejmujące tylko zmodyfikowane atrybuty (np. Pozycję) zmodyfikowanych obiektów oraz oczywiście nowe i usunięte obiekty.

Jak obejść problemy z opóźnieniami?

Głęboko wierzymy w „serwer ma zawsze rację”. Klient dokonuje pewnych prognoz, takich jak płynne chodzenie, kontrole kolizji i tak dalej. Ale jeśli klient i serwer się z czymś nie zgadzają, serwer wygrywa. Podprojekt Stendhal (2D RPG) domyślnie wykorzystuje czas zwrotu 300 ms (z dużą ilością wygładzania po stronie klienta). To sprawia, że ​​Stendhal jest bardzo odporny na opóźnienia.

Uwaga: Niektóre inne gry w pewnym stopniu ufają klientowi, aby zminimalizować wpływ opóźnień w sieci. W WoW był często wykorzystywany na jednym z pól bitewnych zwanym „Wojennym Pieśnią”. Gracz z flagą może wybrać dwa sposoby: na środku przez tunel i jeden po prawej widok na wzgórze. Oszukujący gracz biegnie w kierunku tunelu, a następnie powoduje opóźnienie dla siebie. Serwer i inni klienci będą nadal widzieć, jak biegnie w jego kierunku. Ale po pewnym czasie ten klient może powiedzieć serwerowi, że poszedł w kierunku wzgórza. WoW sprawdzi, czy odległość między ostatnio przesłanymi współrzędnymi a aktualnymi współrzędnymi mieści się w przedziale czasowym i zaakceptuje to.

Zastosowanie UDP vs. TCP

We wczesnych wersjach używaliśmy UDP w celu zmniejszenia obciążenia TCP. Sami poradziliśmy sobie z zagubionymi pakietami. Działało to doskonale na początku projektu. Ale kiedy kilka lat temu serwer został przeniesiony z domowego połączenia DSL do prawdziwego centrum danych, napotkaliśmy ogromne problemy. UDP jest (lub przynajmniej 5 lat temu) niezwykle wymagający pod względem mocy procesora sprzętu zapory: zestaw reguł musi być stosowany do każdego pakietu UDP. Jednak w przypadku TCP zestaw reguł jest stosowany tylko dla pierwszych 3 pakietów. Następnie połączenie zostanie nawiązane. Wszystkie kolejne pakiety ominą normalny zestaw reguł, ponieważ znajdują się w łączącej się tabeli śledzenia lub ponieważ nie mają flagi SYN.

Jak chronić komunikację i klienta przed inżynierią wsteczną?

Arianne to całkowicie otwarte oprogramowanie, w tym klient, serwer, grafika, muzyka. Oczywiście obejmuje to naszą dokumentację protokołu, a nawet analizator używany do debugowania.

Łatwo jest chronić komunikację przed nieautoryzowanym podsłuchiwaniem przez osoby trzecie korzystające z protokołu SSL.

Nie można jednak zabezpieczyć go przed inżynierią wsteczną. Jasne, że możesz go zaciemnić i zastosować techniki antydebugowania. Ale ostatecznie nie można zapobiec inżynierii wstecznej oprogramowania, które rozdaje się użytkownikom. Istnieje bardzo interesująca prezentacja na temat tego, w jaki sposób Skype został poddany inżynierii wstecznej, mimo że programiści włożyli wiele wysiłku w techniki zapobiegania debugowaniu: http://recon.cx/en/f/vskype-part1.pdf

Uwaga: Istnieją kraje, w których inżynieria wsteczna jest nielegalna lub które pozwalają na umieszczenie akapitu w licencji lub WZ, które nie zezwalają na inżynierię wsteczną. Są jednak inne kraje (takie jak ten, w którym mieszkam), które wyraźnie zezwalają na inżynierię odwrotną w kontekście opracowywania kompatybilnych formatów przechowywania danych lub protokołów transmisji, paragrafów w licencji lub warunków świadczenia usług, które są nieważne. (Wszystko w tej części jest o ile mi wiadomo, nie jestem prawnikiem)

Które rzeczy powinny być obliczane lokalnie, a które na serwerze?

Obliczamy wszystko związane z logiką gry na serwerze. Klient przewidzi określone zdarzenia, aby gra przebiegała płynnie. Ale ostatecznie serwer zawsze ma rację.

Przewidywane zdarzenia to na przykład zatrzymanie ruchu po uderzeniu w kolizję. Stendhal używa siatki do pozycjonowania elementów. Z punktu widzenia serwera lewy górny róg każdej jednostki znajduje się dokładnie na jednym kwadracie. Ale klient przenosi je płynnie między płytkami. Narysuje również efekt pseudo 3d. Tak więc jednostka, która ma bazę 1x1, może być wyższa u klienta.

Jak zrównoważyć problemy z obciążeniem?

Staraj się, aby było to tak proste, jak to możliwe, aby ułatwić konserwację.

Równoważenie obciążenia treści statycznych jest dobrze znane w obszarze klastrów serwerów HTTP i sieci dystrybucji treści.

Dość prostą koncepcją równoważenia obciążenia usług gier jest podział serwerów między regiony / strefy. Strefa AC znajduje się na jednym serwerze, a strefy DF na innym. Jest to szczególnie łatwe, jeśli nie możesz patrzeć ze stref w jednym zestawie na strefy w innym zestawie. Musisz umieścić tam kilka czeków, aby klient mógł połączyć się tylko z serwerem strefy odpowiedzialnym za strefę, w której znajduje się gracz.

Najprostszym sposobem na przeniesienie graczy z jednego serwera na drugi jest zapisanie ich w bazie danych, przekazanie klientowi połączenia z innym serwerem strefy i odłączenie go od bieżącego. Klient następnie połączy się z nowym serwerem strefy, który załaduje go z bazy danych. (Ponieważ i tak potrzebujesz obciążenia z / do kodu bazy danych, bezpośrednią komunikację między serwerami w celu przekazania można zaimplementować później).

Potrzebne są dodatkowe usługi globalne poprzez: Podczas logowania klienci muszą zostać poproszeni o połączenie z właściwym serwerem strefy. I możesz chcieć światowego systemu czatu.

Szczegółowo omówiłem ten temat na stronie Jak osiąga się równoważenie obciążenia w MMO?

Hendrik Brummermann
źródło
1
Wspomniałeś, że UDP wymaga nieco więcej procesora, ale nie wspomniałeś, że TCP wymaga co najmniej trzech podróży między klientem a serwerem, zanim pakiet zostanie przetworzony, ORAZ pakiety są buforowane do momentu otrzymania wszystkich poprzednich pakietów, co oznacza, że ​​możesz poczuć się niedorzecznie opóźnienie oczekiwania na pakiety, które nie są już nawet istotne. Wydaje się, że warto o tym wspomnieć.
BlueRaja - Danny Pflughoeft
2
@ Danny, do zainicjowania nowego połączenia TCP wymagane są trzy pakiety: klient do serwera: SYN, serwer do klienta: SYN ACK, klient do serwera: ACK + dane. To o jedną podróż w obie strony więcej niż UDP, ale dzieje się to na samym początku, gdy klient kontaktuje się z serwerem po raz pierwszy. W nawiązanym połączeniu każdy pakiet jest przetwarzany natychmiast, bez żadnych dodatkowych podróży w obie strony. Pojawi się odpowiedź ACK, ale odebrane dane są już przetwarzane, podczas gdy pakiety ACK wracają.
Hendrik Brummermann
1
@ Danny, TCP radzi sobie z utratą pakietów automatycznie iw dość wydajny sposób. Trudno jest ponownie wdrożyć to za pomocą UDP; chyba że twój protokół jest w porządku z losowymi niedostarczonymi pakietami. Kolejnym problemem jest to, że TCP zapewnia, że ​​kolejność pakietów, podczas gdy pakiety UDP mogą być odbierane w niewłaściwej kolejności. Ponownie, trudno jest to zaimplementować samodzielnie, chyba że możesz po prostu zignorować starsze pakiety, na przykład na podstawie licznika pakietów. Jeśli wymagany jest bardzo krótki czas odpowiedzi dla protokołu TCP, algorytm Nagle musi zostać wyłączony.
Hendrik Brummermann
Wygląda na to, że gwałtownie broniłeś swojej pozycji, nie zajmując się bardzo rzeczywistym problemem opóźnienia TCP. Być może prawdziwym problemem jest wybór zapory sprzętowej zamiast protokołu odpornego na DDoS
MickLH
27

http://gafferongames.com/networking-for-game-programmers/

To świetny zestaw artykułów na temat różnych problemów i rozwiązań dotyczących sieci gier.

jsimmons
źródło
1
+1, ale proszę nie ufaj im ślepo. Z mojego doświadczenia wynika na przykład, że używanie UDP i ponowne opracowywanie funkcji TCP nie jest dobrym pomysłem. UPD jest użyteczne tylko wtedy, gdy utracone pakiety nie mają żadnego wpływu, tj. Każdy pakiet UDP zawiera kompletny odpowiedni stan świata. WoW używa protokołu TCP, SL przechodzi z UDP na TCP (nawet HTTP dla treści statycznych) i dzięki tym zmianom znacznie się poprawił.
Hendrik Brummermann
7
Jednak nie wymyślasz na nowo funkcji TCP, przynajmniej nie wszystkich. Kontrola przepływu TCP i semantyka utraty pakietów są straszne dla gry, która wymaga połączenia o niskim opóźnieniu. TCP jest użyteczny tylko wtedy, gdy nie zależy ci na opóźnieniu lub minimalizacji wymaganej przepustowości.
jsimmons
2
Second Life znacznie poprawiło wydajność, przechodząc z UDP na HTTP przez TCP: blogs.secondlife.com/community/technology/blog/2010/08/13/…
Hendrik Brummermann
5
Naprawdę nie poprawili wydajności przesyłania strumieniowego zasobów, zmieniając sposób, w jaki działa. Zastosowanie HTTP / TCP w tym przypadku ułatwiło im wdrożenie, a nie szybciej. Mogę również zauważyć, że zeromq jest ciekawym projektem i może bardzo dobrze skalować się do sieci gier. zeromq.org
jsimmons,
8

W zależności od rodzaju pisanej gry możesz uniknąć programowania niskiego poziomu w sieci. Niektóre rodzaje gier nie wymagają dużej ilości komunikacji między klientami a serwerem. W takich przypadkach można wybrać ramy wyższego poziomu. Na przykład rozwijam turową grę strategiczną w języku C # / .NET. Turowe gry strategiczne są nieco wyjątkowe, ponieważ zdecydowana większość komunikacji klient / serwer odbywa się na początku i na końcu tury, a pomiędzy nimi jest stosunkowo niewiele. Dlatego zdecydowałem się na skorzystanie z Windows Communication Foundation (WCF), struktury komunikacyjnej wysokiego poziomu zaprojektowanej przede wszystkim dla usług sieciowych. Zamiast pracować bezpośrednio z gniazdami i całym tym sprzętem niskiego poziomu, mogę sprawić, że będą to standardowe wywołania metod, i pozwól WCF zająć się protokołem i warstwami transportowymi dla mnie. Jedyny raz, kiedy miałem do czynienia z sieciami niskiego poziomu, było to, kiedy skonfigurowałem swoje punkty końcowe, co jest właściwie jednorazową transakcją w pliku konfiguracyjnym. Nadal konieczne może być zaimplementowanie niestandardowej logiki serializacji, ale musisz to zrobić niezależnie od tego.

Mike Strobel
źródło
8

Pytanie jest zdecydowanie zbyt ogólne. Odpowiedzi mogłyby samodzielnie wypełnić stronę internetową. Ale są na to książki, głównie te dwie:

Pamiętaj, że nawet te książki nie są kompletnym przewodnikiem, ale są zbiorem pomysłów i podejść, których możesz użyć, z których niektóre nie będą ze sobą współpracować, a nawet będą ze sobą sprzeczne. Zazwyczaj zakłada pewne doświadczenie w tworzeniu gier, aplikacji sieciowych lub idealnie obu.

(Zauważ, że mówię więcej o MMO w pierwotnym pytaniu - „gra sieciowa” może oznaczać różne rzeczy, od gry tekstowej opartej na PHP aż po MMO, a powyższe pytania częściowe nie wszystkie dotyczą każdego typu).

Kylotan
źródło
7

Jak zrównoważyć problemy z obciążeniem?

ustalony rozmiar geograficzny + wiele instancji jest najłatwiejszym rozwiązaniem. Faceci pracujący nad SWG wypróbowali dynamiczny rozmiar i tego żałowali.

Jak zarządzać stanem gry?

Serwer jest autorytatywny.

Jak zachować synchronizację?

Okresowe aktualizacje synchronizacji z serwera. (nie jestem pewien, o co tu chodzi)

Jak chronić komunikację i klienta przed inżynierią wsteczną?

Niemożliwy. upewnij się, że nie ufasz niczego, co otrzymujesz od klienta i że serwer jest autorytatywny.

Jak obejść problemy z opóźnieniami?

Ma głębokość mil, ale powierzchownie uruchamiasz tę samą symulację na kliencie, co serwer, a kiedy synchronizacja się dzieje, naprawiaj rzeczy. Wszystkie decyzje podejmowane na kliencie są również symulowane na serwerze, więc mogą być złe decyzje, ale ogólnie rzecz biorąc, wszystko działa.

Które rzeczy powinny być obliczane lokalnie, a które na serwerze?

Pomyśl o kliencie jako o nieautorytatywnej karcie SIM tego, co dzieje się na serwerze. Szybkość reakcji ma kluczowe znaczenie dla doświadczenia gracza, więc musisz coś robić za każdym razem, gdy gracz podejmuje decyzję, nawet jeśli dopiero zaczyna pasek.

Prawdę mówiąc, wiele z tych problemów jest ortogonalnych i mogą mieć później zastosowane rozwiązania. Po prostu zacznij grać i nie przejmuj się zbytnio tymi rzeczami.

Aaron Brady
źródło
4

To pytanie jest bardzo szerokie. Jest to również bardzo trudny obszar do opanowania, programiści sieciowi są bardzo poszukiwani w branży z dopasowanym wynagrodzeniem, co w pewnym sensie wskazuje, że jest to obszar „nierozwiązany”. Czy są tam książki, tak, mnóstwo. Czy są jakieś dobre książki, bez wątpienia. Czy są tam jakieś książki, które odpowiedzą na twoje pytania? Nie sądzę. Mogą mieć rozwiązania, które działają w niektórych sytuacjach lub wskazują na to, czego szukać, ale prawie wszystkie twoje pytania są zależne od gry ... jest to obszar, w którym naprawdę będziesz musiał dużo pracować sam, tak pozornie trywialne i może pójść nie tak na wiele (niekontrolowanych) sposobów.

Kaj
źródło