Network Pong Clone

10

Mam podstawy gniazd TCP, komunikacji UDP itp., Ale nie mogę znaleźć wiele sposobów zastosowania ich w środowisku gry w czasie rzeczywistym.

Mam klon Ponga z 4 graczami i muszę zsynchronizować pozycje wiosła między trzema klientami a serwerem (serwer to czwarty gracz). Obecnie używam UDP do wysyłania aktualizacji w czasie rzeczywistym (ruchy wiosła) i TCP do konfigurowania lobby gry itp.

Czy to ŹLE RZECZ, że spamuje ogromne ilości ruchu UDP? Czy powinienem spojrzeć na coś takiego jak DCCP pod kątem jego funkcji przeciążenia? A może nie jest to problemem w przypadku takiego projektu na małą skalę?

Kiedy należy synchronizować wiadomości między klientem / serwerem? Obecnie serwer wysyła pakiety UDP z bieżącym stanem gry tak szybko, jak to możliwe, a klienci wysyłają spam z powrotem do serwera tak szybko, jak to możliwe. Czy to najlepszy sposób, aby to zrobić? Czy jest jakieś opóźnienie, które powinienem dodać, aby wiadomości były wysyłane raz na X milisekund, czy też powinienem wysyłać wiadomości tylko w przypadku zdarzeń? (np. zmieniono prędkość wiosła na skutek wprowadzenia danych przez użytkownika)

Czy lepiej byłoby zmusić klientów do komunikowania sobie swoich pozycji wiosła między sobą?

Zadaję te pytania w kontekście Ponga, ale jestem również zainteresowany tym, w jaki sposób problemy te zostaną przezwyciężone w innych grach lub ogólnych rozwiązaniach.

elwyn
źródło
Problem, zaraz po opublikowaniu zobaczyłem to: gamedev.stackexchange.com/questions/249/…
elwyn
Kolejne niejasne pytanie: gamedev.stackexchange.com/questions/552/…
Smashery

Odpowiedzi:

5

Mają konfigurowalny interwał aktualizacji (abyś mógł dostosować i wypróbować 5 pakietów na sekundę lub 20), a każda ramka sprawdzi, czy nadszedł czas, aby wysłać aktualizację. Możesz być w porządku z prostą grą wysyłającą pakiety dla każdego wydarzenia, ale w bardziej złożonej grze nie jest to praktyczne. Należy również pamiętać, że istnieje narzut związany z pakietami, więc jeśli wysyłasz kilka małych pakietów, marnujesz przepustowość.

W każdym interwale aktualizacji każdy klient wysyła swoją pozycję wiosła do serwera lub do każdego klienta (peer-peer). Niech serwer wyśle ​​również pozycję kuli i wektor prędkości. Każdy klient może uruchomić ten sam kod rysowania ekranu, co w przypadku pojedynczego gracza, aby ruch piłki był płynny. W grze wieloosobowej masz tylko serwer, który wysyła aktualizacje pozycji / prędkości dla piłki w regularnych odstępach czasu (i jeśli chcesz za każdym razem, gdy coś trafi).

Aktualizacje pozycji piłki odnoszą się do czasu gry dla wszystkich klientów, dzięki czemu możesz odrzucić pakiety poza kolejnością, a nawet dokładniej interpolować pozycję kulek (znasz pozycję i prędkość w określonym momencie w przeszłości, dzięki czemu możesz interpolować nowy pozycja).

W tym modelu z opóźnioną grą możesz czasami zobaczyć, jak piłka porusza się do tyłu lub skacze. Ale z przyzwoitym połączeniem powinno być całkiem gładkie.

kevin42
źródło
5

Jeśli chodzi o kwestie związane z ruchem - nie chcesz wysyłać więcej niż 20-30 pakietów na sekundę na peera. W ogólnym przypadku, jeśli wyślesz mniejsze, mniej pakietów, doświadczysz (nieznacznie) mniejszych opóźnień i mniejszej szansy na odrzucenie pakietów.

Zdecydowanie nie chcesz wysyłać aktualizacji z prędkością większą niż liczba klatek na sekundę, ponieważ gracze nie będą w stanie odróżnić - w rzeczywistości, jeśli wyślesz pakiety tylko 10 razy na sekundę i interpolujesz / ekstrapolujesz wyniki po stronie odbierającej , większość graczy nie zauważy różnicy.

Blair Holloway
źródło
4

To dość szerokie pytanie, ale postaram się podsumować ważne aspekty.

Pierwszą decyzją, którą należy podjąć w kodzie sieci dla twojej gry, jest to, czy chcesz ustawić konfigurację klient / serwer w konfiguracji peer-to-peer. Większość gier, z RTS prawdopodobnie jedynym znaczącym wyjątkiem, prawdopodobnie korzysta z architektury klient / serwer. Główną zaletą jest to, że takie ustawienie jest bardziej odporne na uszkodzenia i zapewnia większą kontrolę nad danymi, które otrzymuje każdy klient. Peer to peer pozwala wysyłać znacznie mniej danych, ale wymaga, aby każdy peer w pełni symulował świat dokładnie tak, jak robi to każdy inny peer. Jeśli jeden z partnerów opóźni się lub zsynchronizuje, każdy musi albo poczekać, aż wyzdrowieje, albo po prostu się zgubi.

UDP jest również ogólnie właściwym wyborem, z pewnością dla każdego modelu klient / serwer. TCP może być praktyczny w przypadku gry typu peer-to-peer, ale nawet wtedy UDP może być lepszym wyborem. Zasadniczo UDP obsługuje mniej dla Ciebie, co oznacza większy wysiłek, ale także większą kontrolę nad sposobem radzenia sobie z usterkami.

Dla Ponga wybrałbym klienta / serwer, ponieważ jest to gra zorientowana na akcję. Należy zwrócić uwagę na jedną rzecz, nawet jeśli mówisz, że jeden gracz „jest serwerem”, najlepiej ustrukturyzuj swój kod tak, aby zasadniczo działał on na serwerze lokalnym i łączył się z nim jako klient.

Zdecydowanie nie chcesz też „spamować” aktualizacji w żadnym kierunku. Wystarczy jedna aktualizacja z serwera na ramkę, a serwer powinien działać ze stałą liczbą klatek na sekundę. To zależy od ciebie, ale nie musisz przesadzać. Klatka 50 ms (20 klatek na sekundę) jest wystarczająca, aby uzyskać przyjemną płynną grę. Aby zachować płynność działania na kliencie, chcesz skorzystać z interpolacji. Klient powinien ciągle przechodzić między migawkami ramek serwera, może to być z pewnością temat osobnego pytania.

Aktualizacje klientów również powinny być ograniczone, choć jedna na ramkę prawdopodobnie będzie zdecydowanie za duża, jeśli klient działa z przyzwoitą liczbą klatek na sekundę.

Jason Morales
źródło
1

Czy zależy ci na oszukiwaniu?

Jeśli nie, przejście peer-to-peer zmniejszy opóźnienie o połowę, ponieważ jest to A <-> C zamiast A <-> B <-> C. Jeśli tak, dla zapewnienia uczciwej synchronizacji możesz nieco opóźnić reakcję lokalnego odtwarzacza lub tego, co robi większość gier - pozwól graczowi zrobić wszystko lokalnie, a następnie cofnij się, jeśli wynik serwera odbiega od symulowanego lokalnie.

Klon ponga jest w rzeczywistości nieco trudny, ponieważ w przeciwieństwie do większości gier, nie możesz (jako twórca) oszukiwać, gdy jedna strona widzi hit, a druga nie.

Jeśli chodzi o coś uogólnionego, jedną z technik, o której słyszałem, ale nie uważałem ich za konieczną (może być w przypadku gier akcji), jest zachowanie akcji z ich prawdziwymi znacznikami czasu (czas odbioru - ping / 2) i przywrócenie serwera ( snap), jeśli pojawi się zdarzenie wcześniejsze, a następnie ponownie zastosuj późniejsze działania. W ten sposób wszyscy są lokalnie konsekwentni, chyba że występuje konflikt wynikający z interakcji różnych graczy. Jedynym niebezpieczeństwem jest możliwość „cofnięcia czasu”, jeśli sfałszują opóźnione połączenie.

James Bellinger
źródło
1

Google martwego liczenia. Wysyłanie aktualizacji dla 4 graczy nie będzie znaczące. Ilość przesłanych danych będzie rzędu bajtów. Oznacza to, że częste aktualizacje powinny być w porządku. Przy martwym rozrachunku gracz przesuwa się na klienta i serwer. Serwer jest autorytetem. Gdy pozycja klienta staje się zbyt daleko od synchronizacji z serwerem, musi powrócić do wyrównania. http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/Quake3Networking Korzystanie z protokołu UDP jest właściwą drogą. Często będą wysyłane aktualizacje, że utracone dane zostaną wkrótce zastąpione danymi przychodzącymi. Retransmisja pakietów TCP nie jest tego warta dla pozycji gracza. Przeczytaj ten artykuł, aby uzyskać więcej informacji na temat synchronizacji klienta i serwera.

zooropa
źródło
-1, niska zawartość i [obecnie] błędnie napisane. Liczenie jest martwe .
Tetrad
Usunąłem moją opinię.
Tetrad
0

Kilka tygodni temu zaprogramowałem grę dla 2 graczy w sieci lokalnej w ponga, oto jak to zrobiłem:

- Jedna strona otwiera serwer, druga łączy się automatycznie - obaj spamują swoje wiosła x pozycję do siebie @ 60 fps lub mniej [UDP] - jeśli jedna strona uderzy w piłkę, decydują o nowej prędkości i pozycji piłek i wysyłają to do drugiej [TCP] - jeśli piłka leci obok wiosła, zawodnik, który ją przegapił, kontaktuje się z drugą z komunikatem o podwyższeniu wyniku i piłka jest resetowana [TCP] - piłka jest cały czas symulowana niezależnie, co pasuje do prostej fizyki piłki do ponga

Tworzy to około 0,3 do 0,5 kB / s ruchu przy 60 klatkach na sekundę, a gracze nie mają opóźnień w postrzeganiu, ale tylko wtedy, gdy ping jest poniżej pewnego progu, ponieważ należy przekazać nową pozycję piłek.

Również oszukiwanie jest łatwe dzięki temu systemowi i istnieje duża szansa na zsynchronizowanie się z bardzo stratnym połączeniem, ale kogo to obchodzi oszukiwanie w pongu ?!

VaTTeRGeR
źródło