Skocz do zawartości

Źle wysłana wiadomość w networkingu


Sutikku

Rekomendowane odpowiedzi

Korzystam z Game Makera Studio, wersja standard i tak. Podchodziłem do tematu networkingu wiele razy. I wszystko działa, dopóki testuje u siebie. Ale jak dam komuś, to jeśli ten ktoś, ma problemy z internetem, to mu jakby odbiera złe wartości. I prędzej czy później wywali to jakiś error z tym związany. Korzystam z połączenia TCP. Czy to normalne? Jak tego uniknąć? Zauważyłem, że jeśli nie wysyłam zbyt wiele dużych wiadomości, to jest spoko. No i staram się ograniczać, ale to czasem nie pomaga. A w moich grach to naprawdę minimum, 5 graczy maksymalnie, każdy x i y.

Odnośnik do komentarza
Udostępnij na innych stronach

Dane X i Y, wysyłam w momencie, w którym jest przytrzymany przycisk u klienta. Więc w sumie jeśli się ktoś porusza, to 60 na sekundę od klienta. Jak teraz nad tym pomyślę, to nawet dużo. A od serwera, wysyłam do klientów te same informacje o ruchu. A korzystam z buffer_fixed. buffer_seek_start, mam dawać za każdym razem, jeśli korzystam "od nowa" z zapisywania bądź wczytywania. Tutaj w sumie mam tak to zrobione, że nie ma raczej bata, żebym czasem coś źle użył. Przeważnie to buffer_s16. Próbowałem kiedyś też mapę wysyłać do klienta na początku gry, ale to też wywalało często błędy. Zniwelowałem to, wysyłając jeden blok co 20 stepów, ale nadal coś nie tak. Myślałem nad czymś takim, jak wysyłanie jakby tej samej wiadomości dwa razy, a raczej ID wiadomości, jak będzie nie tak coś, to ją zignorować, ale to chyba tylko bardziej zalaguje serwer.

Odnośnik do komentarza
Udostępnij na innych stronach

W tym wypadku error wychodzi z tego, że np. ja do bufferu planuje wysłać klientowi

Msg_id 1

380 (x)

273 (y)

 

A klient dostaje np.

msg_id 13

tutaj nawet nie wiem co

I wysypuje error, bo tutaj jest na przykład przyłączenie nowego gracza i wychodzi poza tablicę graczy, bo poda jakąś dziwną wartość.

I zauważyłem, że to dzieje się za każdym razem, kiedy klient zaczyna mieć jakieś lagi, stąd taki wniosek.

Także errory są przeróżne, różnie to bywa.

Odnośnik do komentarza
Udostępnij na innych stronach

Sprawdziłem. Zawsze, ale to zawsze korzysta (a przynajmniej powinno) z buffer_u8. A maksymalny wysyłany msgid to uwaga, 7. Podpatrzyłem ten przykład Lan_platformer i chociaż jest według mnie dość nieczytelny to sprawdziłem jak często wysyłane są tam wiadomości i w jakiej wielkości. Średnio co pół sekundy, sekundę o wielkości 6 bajtów. Ja wysyłam 7 bajtowe 60 razy na sekundę. Może stąd problem. Próbuję to teraz pozmieniać i zrobić "mądrzej". Tylko tak się teraz zastanawiam. Jak tworzę buffer, to ustawiam jego wielkość na 1024. Tak powiedział internet, tak zobaczyłem więc tak robię. A czy to w takim razie nie jest za dużo jak na 7 bajtowe pakiety? I czy zmniejszenie go, znacznie wpłynie na optymalizacje tego wszystkiego?

Odnośnik do komentarza
Udostępnij na innych stronach

Okej, wybacz, zapomniałem o temacie:

 

1. Używaj buffer_grow (ja używam buffer_create(1024,buffer_grow,1); i nigdy mnie nie zawiodło)

2. 60 razy na sekundę to DUŻO za dużo. Musisz wysyłac rzadko, ale wprowadzić wygładzanie ruchu i lag compensation. To dużo roboty, ale tak wszystkie gry robią.

3. Mając buffer grow pamiętaj aby wysyłać tylko tyle ile trzeba, czyli w argumencie wielkości bufera podaj buffer_get_size(nazwa_buffera)

 

Twoje problemy mogą wynikać z tego, że za szybko wysyłasz i/lub próbujesz wysłać więcej niż bufor może utrzymać(Nie zauwazylem, ze podales wielkosc bufera, ma 1024B, więc jak wyślesz 1x8 i 2x16 używasz tylko 7B o ile nie walnąłem się w matmie. Niemniej, nadal zalecam Ci zmianę na grow..)

Odnośnik do komentarza
Udostępnij na innych stronach

Przepisałem cały silniczek od nowa. Teraz wysyłam informację tylko o naciśnięciu klawisza. Ale serwer nadal wysyła tak często dane, bo on już wysyła gotową pozycję. A wolałem, żeby wszystko działo się po stronie serwera. Zrobić taki myk jak na serwerze? Wysłanie tylko aktualnie wciśniętego przycisku i od czasu do czasu wysyłać poprawkę? Zmieniłem już na buffer_grow. Zamiast buffer_get_size(), korzystam z buffer_tell(), to chyba to samo? Z tym, że wcześniej sam system wysyłania pozycji był bardzo żerny, bo wysyłałem informację od klienta do serwera, gdzie jestem (x, y, buffer_s16) i serwer samą tą informację wysyłał do każdego z graczy. Teraz wysyłam od razu pozycje wszystkich graczy.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeżeli serwer w równych odstępach czasu wszystkim mówi pozycje wszystkich graczy tak jak je obecnie zna, to dużo lepsze wyjście niż poprzednie.

Podawanie pozycji zrób na clientside, ale wszelkie inne dane (zdrowie, itd) trzymaj po stronie serwera, koniecznie. Jeżeli martwią Cię speedhacki do których może dojść manipulacją pozycji gracza, to trzymaj informację o odległościach czasowych między update'ami gdzieś w danych serwera (używaj do tego current_time) i sprawdź czy prędkość na sekundę(wektor z ostatniego updateu do obecnego) nie przekracza jakieś absurdalnej wartości, której nie ma prawa przekroczyć(np. 110% standardowej prędkości postaci).

 

Jeżeli chodzi o buffer_tell - Nie miałem okazji tego używać, z opisu w dokumentacji nie jestem pewien, czy to dobre rozwiązanie, bo pozycja wewnąrz bufera, a faktyczna wielkość, która może się różnić przez nagłówki(czy coś podobnego, czego nie jestem dokładnie świadom) to mogą być dwie różne rzeczy. Jeśli możesz poświęć czas na zmianę w kodzie aby używać buffer_get_size, dla uniknięcia problemów.

 

teraz na sam koniec: Jeśli chodzi o tylko informacji o naciśnięciu klawisza, jeżeli będzie Ci tak działało, to okej. Osobiście zrobiłbym to inaczej.

Odnośnik do komentarza
Udostępnij na innych stronach

Zrobiłem tak. Klient podaje informacje co nacisnął, pozycja ogarnia się na serwerze, wysyłam do klienta też informacje o przyciskach i u klienta robię to samo z pozycjami. Co dwie sekundy wysyłane są poprawki x i y. Ale u klienta to powoduje cofania dość duże, przez co wszystko gorzej wygląda. Jak mogę to zrobić lepiej?

Odnośnik do komentarza
Udostępnij na innych stronach

Już powiedziałem: Klient kontroluje X i Y, serwer nie kwestionuje jakie wartości tam dostanie, chyba że chcesz anti speedhack wpisać w kod, to wtedy (w serwerze!) wyliczasz odległość ze starej pozycji na nową i mnożysz przez (czas od ostatniego update w ms / 1000) aby okreslić prędkość w pikselach na sekundę. Jeżeli prędkość w pikselach na sekundę nie przekracza normalnych wartości, zostawiasz go w spokoju, jeżeli przekracza, to czituje. I cokolwiek z nim wtedy zrobisz to Twoja sprawa.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 rok później...

Nie wiem czy GM ma jakis własny bufor na te pakiety z TCP, ale np. w UE4 odradza sie wysyłanie pakietów po TCP (tam to sie nazywa reliable) tak często jak ty to robisz, bo w ich silniku może dojść do przepełnienia bufora i nawet crasha.

Tak czy siak robiłem sporo gierek z sieciówką w GMie swojego czasu i nigdy nie potrzebowałem wysyłać pakietów "co stepa". W ogóle pozycje to raczej polecałbym po UDP, troche mniej niż 60 razy na sekundę i zastosować jakąs interpolacje/przewydiwanie ruchu.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...