Dane wejściowe po stronie serwera


9

Obecnie w mojej grze klient jest jedynie rendererem. Gdy stan wejściowy zostanie zmieniony, klient wysyła pakiet do serwera i przesuwa odtwarzacz tak, jakby przetwarzał dane wejściowe, ale serwer ma ostatnie słowo na temat pozycji.

To ogólnie działa bardzo dobrze, z wyjątkiem jednego dużego problemu: spadania krawędzi. Zasadniczo, jeśli gracz idzie w kierunku krawędzi, powiedz na klifie, i zatrzymuje się tuż przed zejściem z krawędzi, czasem sekundę później, zostanie teleportowany z krawędzi. Wynika to z faktu, że pakiet „Przestałem naciskać W” jest wysyłany po przetworzeniu informacji przez serwer.

Oto schemat opóźnień, który pomoże Ci zrozumieć, co mam na myśli: http://i.imgur.com/Prr8K.png

Mógłbym po prostu wysłać pakiet „W Pressed” do każdej ramki do przetworzenia przez serwer, ale wydaje się to rozwiązaniem kosztownym dla przepustowości.

Każda pomoc jest mile widziana!

Odpowiedzi:


5

Podczas gdy serwer ma ostatnie słowo w sprawie pozycji, powinien to zrobić, weryfikując i sprawdzając, co klient wysyła jako dane wejściowe i pozycję. Mówię to, ponieważ to, co robisz, powoduje natychmiastowe przesunięcie odtwarzacza, a oczekiwanie, które tworzy się w kodzie, jest takie, że klient jest prawdziwą pozycją.

Myślisz, że ogólnie działa dobrze, ale tak nie jest. Uwaga dodatkowa: mówisz, że twój klient jest niczym więcej niż rendererem, a następnie niezwłocznie dajesz mu kontrolę lokalną, aby poruszać się bez komunikatów serwera. Nie możesz tego zrobić na dwa sposoby, albo poczekaj, aż serwer powie ci się przenieść, albo przejmij kontrolę nad swoją pozycją i użyj serwera do weryfikacji kodów.

Zauważam, że twoje odpowiedzi sięgają jednej sekundy? To opóźnienie 500 ms, które jest absurdalnie duże dla każdej gry akcji. Spróbuj dowiedzieć się, dlaczego ta zmiana trwa tak długo, może to być wszystko, od tworzenia kopii zapasowych kolejek poleceń, od braku szybkiego reagowania, po zalanie przepustowości, a nawet demony powodujące wiele utraconych pakietów.

Myślę, że to powinno się zdarzyć

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

Problem polega na tym, że jeśli klient otrzyma wiadomość o sobie, powinien ją w większości zignorować, chyba że jest to coś w rodzaju „nieprawidłowy ruch, zamiast tego przejdź do XYZ”. Jeśli ta wiadomość jest skierowana do klienta innego, o którym otrzymujesz informacje, musisz ekstrapolować w przód, aby wyglądało na to, gdzie będzie.


Klient wcale nie wysyła swojej pozycji; po prostu przewiduje / interpoluje. Dlatego spada z krawędzi, gdy myśli, że jest na krawędzi. Ponadto nie widzę, gdzie powiedziałem, że opóźnienie wynosi 1 sekundę, jest bardziej jak 8ms (testy lokalne) do 100ms (przez Internet). Powiedziałem, że gracz wraca później, ponieważ okresowo wysyłam pełne aktualizacje pozycji. Czy mam rację rozumiejąc, że powinienem wysłać stanowisko, które według klienta powinno być, wraz z naciśniętymi klawiszami, a serwer powinien sprawdzić, czy jest to możliwe?
Thomas

„czasem sekunda później zostanie teleportowany” implikuje duże opóźnienia, z których mam czas. W przypadku responsywnej gry akcji tak, klient gra, a serwer gra z opóźnieniem i informuje go, czy zrobił coś nielegalnego. Zauważysz, że w grach online dla wielu graczy widzisz, jak inni ludzie zmieniają pozycje (te pochodzą z serwera), podczas gdy twoja własna pozycja bardzo rzadko zmienia się od bezpośrednich poprawek serwera. Inni ludzie widzą, że zmieniasz pozycję itp.
Patrick Hughes

Czy nie może to jednak spowodować, że gracz spadnie z krawędzi na serwerze? O ile nie wyślę pakietu w każdej ramce, serwer może nadal myśleć, że odtwarzacz porusza się przez około 32 ms. (Wysyłam pakiety tylko co trzy ramki). A może sugerujesz, że wcale nie symuluję danych wejściowych na serwerze, a jedynie sprawdzam, czy pozycja jest w granicach wciśniętego wejścia?
Thomas

Ponieważ serwer koryguje tylko nieprawidłowy ruch zgłoszony przez klienta, nigdy nie wyśle ​​„spadłeś z klifu”, chyba że sam klient przejechałby tuż nad krawędzią. W tej pętli sprzężenia zwrotnego serwer koryguje się do poglądu klienta na świat i jego miejsce w nim. Ruch będzie wydawał się szybki i wrażliwy na gracza. Inne działania, takie jak interakcja z obiektami świata, polegają na czekaniu, aż serwer powie klientowi, co się właśnie wydarzyło, kliknij pole i czekaj na odpowiedź, ale mówimy tylko o ruchu tutaj.
Patrick Hughes

Brzmi bardzo podobnie do tego, co obecnie robię; wysyłanie pozycji do serwera i sprawdzanie, czy gracz mógł przejść do tej pozycji. To wydaje się być bardziej heurystyczne i moim zdaniem nie byłoby prawie tak skuteczne, jak decyzja serwera. Czy wysyłanie znaczników czasu przy każdym pakiecie działałoby? Myślę, że to wyeliminowałoby problem. Uważam, że Halo i gry wykorzystujące silnik Source używają tego.
Thomas

0

Rozumiem twoje pytanie jako:

Serwer dostaje pakiet, gdy zaczynam naciskać przycisk „do przodu”, a inny pakiet, kiedy w końcu puszczam przycisk „do przodu”. Dlatego rzeczywisty ruch na serwerze rozpoczyna się i kończy około 100 milisekund „za późno” w rzeczywistej grze w porównaniu z tym, co gracz wyraża po stronie klienta. Więc jeśli gracz chce przesunąć się o 10 sekund, może skończyć się ruchem 10x sekund zamiast tego w x >= 1trybie online.

Jest to zła strategia projektowania, ponieważ nie wyraża woli gracza w świecie gry, tak jak chce, co powoduje raczej słabe wrażenia użytkownika.

Rozwiązaniem, które polecam, jest wysyłanie pakietu (tak często, jak to możliwe), który wskazuje, ile kroków gracz zrobił i w jakim kierunku. Serwer następnie aktualizuje świat gry o nową lokalizację gracza, jeśli przejdzie kontrolę poprawności. Dzięki temu gracz może poruszać się z dużą precyzją i unikać spadania z wysokich półek.

Alternatywą byłoby zapamiętanie pozycji gracza w ostatniej sekundzie i skorygowanie pozycji z perspektywy czasu zwolnienia przycisku. Wygląda na to, że tworzyłby ten efekt gumki z dawnych czasów. (Tylko z innego powodu)

Zasadniczo musisz wysłać pakiet, który przycisk został wciśnięty i jaki był faktyczny czas gry, który został naciśnięty, a następnie, który przycisk został zwolniony i o której godzinie.


Jak powiedziałem Patrickowi, myślę, że to rozwiązanie byłoby bardziej heurystyczne; zamiast serwera będącego „Człowiekiem”, serwer sprawdza poprawność danych klienta. Będzie to oczywiście wymagać pewnej swobody, aby opóźnienia lub inne problemy z siecią nie powodowały fałszywych trafień.
Thomas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.