Myślałem o grze RTS dla wielu graczy. Częścią, której nie mogę się obejść, jest synchronizacja ruchu jednostek. Jeśli przesunę jednostkę A w celu wykrycia XY, muszę przekazać ją z powrotem do serwera, który przekaże drugi klient.
Jestem ciekawy, jak wyglądałaby komunikacja. Czy po prostu poinformowałbyś serwer, że przenoszę jednostkę A do XY z JZ? Może zamiast tego musisz komunikować koordynację ruchu przez koordynację? Jaka jest najbardziej efektywna metodologia komunikowania przepływu jednostek między klientami?
EDYTOWAĆ
To jest nowe pytanie od stackoverflow . Odkryłem, że ta strona była prawdopodobnie lepszym miejscem na pytanie.
Jedna z lepszych odpowiedzi z tego postu:
Zakładam, że zamierzasz użyć paradygmatu sieci klient-serwer? W takim przypadku nie można ufać klientom, że poradzą sobie z faktycznym pozycjonowaniem jednostek, należy przekazać to zadanie serwerowi. Następnie bierzesz listę poleceń od każdego klienta za każdym tikiem i obliczasz ruch każdej jednostki, po zakończeniu tej czynności, następnie zaznaczasz pozycję każdej jednostki odpowiednią dla każdego klienta (na podstawie całej mapy lub na podstawie widoku) i ponownie rozpocznij proces.
Odpowiedzi:
Nie chcesz synchronizować pozycji wszystkich jednostek z serwera do każdego klienta; zajmie to znacznie więcej przepustowości niż potrzebujesz. Musiałbyś również mieć do czynienia z interpolacją / ekstrapolacją pozycji jednostek itp. Prawie żaden profesjonalny klient / serwer nie korzysta z usług RTS!
Zamiast tego chcesz wysyłać tylko polecenia graczy. Zamiast przesuwać jednostki natychmiast po kliknięciu przez gracza, ustawisz w kolejce polecenie ruchu, które ma być wykonane w pewnym momencie w przyszłości - zwykle tylko kilka klatek. Każdy wysyła swoje polecenia do wszystkich. Kilka klatek później wszyscy wykonują wszystkie polecenia, a ponieważ gra jest deterministyczna, wszyscy widzą ten sam wynik.
Minusem jest to, że każdy gracz jest tak wolny jak najwolniejszy gracz - jeśli ktoś pozostaje w tyle w wysyłaniu poleceń, wszyscy muszą zwolnić i czekać, aż nadrobi zaległości (w Starcraft 2 to jest „XXX spowalnia grę „ okno dialogowe).
W rzeczywistości zwykle wykonuje się jeszcze jedną rzecz: całkowicie wyeliminować serwer . Niech każdy klient wyśle swoje polecenia do każdego innego klienta. Zmniejsza to opóźnienie (zamiast polecenia wysyłanego od ciebie -> serwer -> przeciwnik, po prostu idzie od ciebie -> przeciwnik) i ułatwia kodowanie, ponieważ nie musisz już kodować osobnego serwera. Ten rodzaj architektury nazywa się peer-to-peer (P2P).
Minusem jest to, że teraz potrzebujesz sposobu rozwiązywania konfliktów, ale ponieważ polecenia większości graczy są niezależne od siebie w większości RTS, zazwyczaj nie stanowi to większego problemu. Ponadto nie skaluje się dobrze - za każdym razem, gdy dodajesz nowego gracza, każdy gracz musi wysłać mu swoje polecenia. Nie będziesz robić MMO RTS za pomocą P2P.
Ta konfiguracja (wysyłanie tylko poleceń za pomocą P2P) jest sposobem działania większości RTS, w tym Starcraft, C&C i AoE, i jest jedynym sposobem, w jaki AoE może obsługiwać 1500 jednostek przy połączeniu 28,8 kb / s .
Oto kilka dodatkowych wskazówek dotyczących pisania RTS P2P:
rand()
,cos()
etc, ale prawie wszystko zmiennoprzecinkową matematyka jest wykluczone (patrz tutaj , tutaj i tutaj ) ! W takim przypadku lepiej będzie użyć klienta-serwera.źródło
Zrobiłem RTS w sieci TCP, w którym sam przekazałem polecenia, a nie ich wyniki . Na przykład gracz wydaje rozkaz ruchu. Jeśli zamówienie przeniesienia jest ważne według tego klienta, jest wysyłane na serwer. Serwer następnie odsyła go z powrotem do wszystkich klientów, którzy go sprawdzają i wykonują.
Więc wszystkie komputery klienckie same uruchamiają grę, kod serwera przyjmuje wiadomości i odsyła je z powrotem do wszystkich klientów. Jeśli klient wyda polecenie przeniesienia, nie zacznie go wykonywać, dopóki nie zostanie odebrane z serwera.
Serwer wysyła również „tik”, pod którym należy wykonać polecenie, czyli kilka tyknięć przed „bieżącym” tikiem. W ten sposób wszystkie polecenia mogą być wykonywane na tym samym „tykanie” na wszystkich komputerach.
Jedną z zalet tej metody jest to, że sprawdzanie poprawności polecenia nie zależy od pojedynczego komputera klienckiego. Jeśli przejdę wyniki ruchu, być może uda mi się go zhakować, aby szybciej przenieść moje jednostki. Wszyscy klienci muszą wykonać to samo polecenie, a jeśli jedna maszyna wykona je inaczej, będzie to oczywiste.
Sprawdzanie poprawności polecenia po stronie klienta przed wysłaniem go do serwera nie jest konieczne, ale teoretycznie oszczędza ruch sieciowy. Użyłem tego samego kodu sprawdzania poprawności, aby poinformować interfejs użytkownika, że przeniesienie było możliwe, więc nie wymagało pisania dodatkowego kodu.
Co do tego, jak mogą wyglądać wiadomości. Nie interesowała mnie ultra wydajność, ponieważ była to moja pierwsza gra sieciowa. Polecenia przekazałem jako ciągi znaków. Polecenia będą sformatowane w następujący sposób:
"<player_id>:<command>:<parameters>"
Na dobry przykład, polecenie ruch może wyglądać następująco:
"3:move:522:100:200"
. Oznacza to, że Gracz3
chcemove
połączyć się522
z (100
,200
).Serwer przekazuje polecenia do wszystkich klientów, w tym jeden, który wysłał go z numerem kleszcza załączonym tak:
"153238:3:move:522:100:200"
.Następnie wszyscy klienci wykonaliby to polecenie, gdy zostanie wykonany tyk 153238.
źródło