Tworzenie gry. Logika po stronie serwera i klienta

0

Cześć!
Piszę grę przeglądarkową (canvas) i zacząłem się zastanawiać nad tym co powinno wykonywać się po stronie serwera a co po stronie klienta.
W wielkim skrócie gra 2d, chodzenie w każdym kierunku, ściany, jakieś skrzynie z przedmiotami. Strzelanie z wielu rodzai broni (różne strzały np. wiele strzałów w podobnym kierunku - shotgun, pojedynczy strzał - pistolet, strzały które się rozszerzają, oczywiście każda broń strzela cały czas, ma własny odrzut). Przeciwnicy - podstawowe SI, różne zachowania, szukanie drogi. Spawnery spawnujące przeciwnkiów.

Czy klient ma tylko być "inputem" tz wysyłać dane na serwer że gracz nacisnął strzałkę do przodu, czy w jakim kierunku jest myszka względem niego, a cała "gra" ma odbywać się w backendzie i tylko przesyłać do klienta info co i gdzie ma wyświetlić? Czy takie podejście nie będzie powodowało zbyt dużych opóźnień (gra jest dość szybka, było by trzeba wysłać min 30 pakietów danych na sekundę). Czy jednak zostawić część obliczeń w kliencie? Jeśli tak to jakie?

Dodam że klient to na razie javascript który może być edytowany przez klienta. W czasie dojdzie multiplayer.

Z góry dziękuję za pomocne odpowiedzi :)

1

Wiele gier robi i jedno i drugie. Tzn klient niby prowadzi swoje obliczenia ale co 1-2 sek następuje synchronizacja z serwerem. Dzięki temu zmniejsza się szansa że ktoś zmodyfikuje klienta żeby uzyskać dodatkowe możliwości :)

0

@Shalom: Robiąc to w taki sposób jak mogę walczyć z błędami sieci? Wystarczy że jeden pakiet nie dojdzie w którym będzie naciśnięty klawisz i już klient jest cofany mimo że nic złego nie robi.

1

Od tego jest TCP, żeby pakiety się nie gubiły.

EDIT: Oczywiście, w przypadku dynamicznej gry multiplayer, to będzie zbyt wolne.

0

@Kele:
Używanie TCP w grach bywa bardzo często absolutnie fatalnym pomysłem. Tu się liczą możliwie małe opóźnienia, jak pakiet nie dojdzie szybko, to już nas w ogóle nie interesuje. Nie ma sensu opóźniać kolejnych, bo któryś się zgubił w sieci i trzeba go wysyłać ponownie.

@NickOver:
A to jest zazwyczaj już problem klienta. Twoim zadaniem jest taka implementacja protokołu sieciowego, by nie było zbytnio możliwości wykorzystywania celowo wywoływanych problemów z siecią przeciwko innym graczom, ale chociaż zapewnienie możliwie płynnej gry przy słabym połączeniu byłoby czymś fajnym, to niemal zawsze kłóci się z zasadą nadrzędną.

0

@Althorion:
Sam wspomniałeś, że chcesz @Shalom wspomniał, że można robić synchronizację co jakiś czas, nie w czasie rzeczywistym. Naprawdę nie da się wtedy zdzierżyć tych opóźnień?

1

Bardzo zależy, co robisz. Jak jest to np. gra turowa, to TCP jest jedynym sensownym rozwiązaniem, bo musisz mieć wszystkie dane i opóźnienia nie przeszkadzają. Ale jeśli jest to gra o jakimkolwiek dynamizmie, powiedzmy strzelanka sieciowa, to TCP Ci tę grę zabije. Nie da się zdzierżyć takich opóźnień. M.in. dlatego, że opóźnienia jednego gracza wpływają na wszystkich pozostałych.

Typowe rozwiązanie jest takie, jak to opisał Shalom — tzn. gracz wysyła serwerowi dane, serwer wysyła jemu i co jakiś czas synchronizujesz. Przez co na przykład wygląda to tak, że gracz strzela, lokalnie jest rozwiązywane, czy trafił i do tego jest dopasowywana animacja, gracz wysyła dane serwerowi o tym, jak strzelał, serwer analizuje, czy trafić mógł i odsyła stan gry do wszystkich graczy. W tym momencie dopiero gracz strzelający się dowiaduje, czy faktycznie trafił. Widać to było np. w grze Battlefield 3 (ostatni, w którego grałem; pewnie dalej jest tak samo, ale nie jestem pewien), gdzie czasami był zauważalny odstęp pomiędzy animacją śmierci przeciwnika a dostaniem punktów za zabicie go.

Takie rozwiązanie doprowadza jednak do sytuacji nazywanej „peekers advantage” — gracz wyłaniający się zza winkla rozwiązuje lokalnie to, że widzi przeciwnika, strzela, wszystko jest legalne, więc serwer mu to zalicza. Ale jeśli zrobił to odpowiednio szybko, to zabity mógł nie zdążyć dostać i przetworzyć informacji o tym, że ktoś się zza rogu wyłonił, więc z jego perspektywy został zabity znikąd.
Jednym z rozwiązań jest lokalne przewidywanie ruchów innych postaci w grze. Jeśli się z niego skorzysta, peekers advantage jest w dużej mierze niwelowana, ale pojawia się zupełnie inny problem — ghosting. Jeśli gracz biegł w kierunku wyłomu, ale się nagle zatrzymał, to jego przeciwnicy o słabszym połączeniu sieciowym mogli nie dostać na czas informacji z serwera o tym, więc z ich perspektywy on wyszedł zza rogu, być może go zastrzelili, i dopiero potem serwer im mówi, że jednak tak nie było.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.