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?