Gra sieciowa dobry/optymalny sposób wymiany danych

0

Gra sieciowa i wybór dobrego/optymalnego sposobu wymiany danych między graczami.

A więc pisze pewną grę sieciową generalne gra będzie 2D (zapewne rzut izometryczny). Gra będzie w postaci apletu.
Na chwilę obecną mam już w jakimś stopniu działający serwer i klienta.
Obecnie wygląda to tak, że odpalam sobie serwer następnie Firefoxa łącze się z serwerem i pojawia się w oknie apletu obiekt gracza, (którym jak na razie oprócz poruszania się nic innego nie potrafi) następnie odpalam IE i robię to samo z tym, że po połączeniu w oknie Firefoxa pojawia się obiekt nowego gracza, którego ruchy są odbierane z serwera.
Dodatkowo na serwerze przechowuję aktualne dane o położeniu wszystkich graczy (i zapewnie w przyszłości inne dane).
Klient gracza również zawiera listę z obiektami, które reprezentują graczy połączonych z serwerem.

A teraz moje pytanie jak będzie lepiej przekazywać dane o położeniu/stanie obiektu gracza.
Na chwilę obecną robię to przy użyciu wartości typu String, czyli jeżeli poruszę się graczem to tworzę odpowiednią wiadomość a następnie wysyłam na serwer, serwer z kolei rozsyła tą wiadomość do wszystkich połączonych klientów graczy następnie klient parsuje tą wiadomość i aktualizuje odpowiedni obiekt gracza.
Przykładowy wygląd wiadomości
[x][8][103]
X – oznacza, że obiekt zmienił pozycję na osi x
8 – unikalny identyfikator gracza (w jakiś sposób muszę ich rozpoznawać)
103 – aktualne położenie gracza na osi X (czyli to, co się zmieniło)

No więc co o tym sądzicie? Czy ten sposób będzie w miarę optymalny czy lepiej przesyłać obiekty graczy gdyż będzie to optymalniejsze od parsowania stringa. Wydaje Mi się jednak, że obiekt będzie zdecydowanie większy i w przypadku wrzucenia apletu na stronę może powodować lagi w grze.
Czytałem na tym forum kilka wątków odnośnie pisania gier, z których wynikało, że najpierw piszemy a potem optymalizujemy niestety w tym przypadku wolałbym ten mechanizm zrobić w miarę poprawnie od początku.

Nie wiem czy idę dobrą drogą w sumie to pierwszy raz piszę grę (chociaż nie pierwszy raz piszę aplikację). Tak naprawdę to grę piszę hobbistycznie zawsze chciałem jakąś napisać :).
Być może macie jakieś ciekawe strony poruszające temat komunikacji sieciowej pomiędzy graczami.

0

Na mój rozum-prymitywne rozwiązanie jest zawsze najlepsze:) Twoje wydaje się najlepsze:) Ale niech wypowiedzą się bardziej doświadczeni. Oczywiście te rozwiązanie zakłada , ze nikt nie będzie oszukiwał...

PS: Jestem ciekaw wyniku-w aplecie rzut izometryczny no no - daj linka jak możesz bom ciekaw...mogę testować.

Pozdro

0

Sugeruję zrobić jakieś uwierzytelnianie i szyfrowanie połączenia. Serwer powinien posiadać swój klucz prywatny. Identyfikację można zrobić nawet po kluczu publicznym klienta (ale trzeba zrobić protoków odporny na ataki chociażby man-in-the-middle czy też preparowanie fałszywych wiadomości z nieprawidłowymi kluczami). Serializację można zrobić za pomocą np Googlowego Protocol Buffers jeśli Javowa serializacja jest niesatysfakcjonująca. Do GUI Appletu możesz użyć JavaFX.

Jak się łączysz? Po RMI czy czysty HTTP? W sumie to się nie orientuję, chyba w Aplecie tylko czyste HTTP jest dozwolone. HTTP i tak powoduje spory narzut poprzez duże nagłówki i krótkie czasy Keep-Alive (chociaż jeśli ruchy będą odpowiednio częste to te krótkie czasy wystarczą).

0

Dzięki za wasze opinie.

lipkerson napisał(a)

Oczywiście te rozwiązanie zakłada, ze nikt nie będzie oszukiwał...

Na chwile obecną tak ;).

lipkerson napisał(a)

Jestem ciekaw wyniku-w aplecie rzut izometryczny no no - daj linka jak możesz bom ciekaw...mogę testować.

Jak doprowadzę parę rzeczy w kodzie do ładu to podeślę namiary.

donkey napisał(a)

Sugeruję zrobić jakieś uwierzytelnianie i szyfrowanie połączenia. Serwer powinien posiadać swój klucz prywatny. Identyfikację można zrobić nawet po kluczu publicznym klienta (ale trzeba zrobić protoków odporny na ataki chociażby man-in-the-middle czy też preparowanie fałszywych wiadomości z nieprawidłowymi kluczami). Serializację można zrobić za pomocą np Googlowego Protocol Buffers jeśli Javowa serializacja jest niesatysfakcjonująca.

Podejrzewam, że na chwilę obecną mogę o tym nie myśleć. Aczkolwiek dzięki za radę sprawdzę to zanim zabiorę się za GUI.

donkey napisał(a)

Do GUI Appletu możesz użyć JavaFX.

Pożyjemy zobaczymy.

lipkerson napisał(a)

Jak się łączysz? Po RMI czy czysty HTTP?

No cóż na chwilę obecną używam soketów.

Jak już pisałem wszystko to robię hobbistycznie i jak mam czas i siły to się tym zajmuję (aczkolwiek ostatnio trochę czasu na to poświęcam :)).

0

Stringi to raczej nie jest optymalny sposób przesyłu danych.
Twój sposób jest łatwy w implementacji w sumie, ale jeśli to ma być gra real time na dużo graczy, to chyba za dużo niepotrzebnych danych się śle.
dla przykładu
[x][42][511]
jeśli przesyłasz kodując UTF8 - 12 bajtów
jeśli na czysto jak javowe stringi - 24 baty
i to na samą oś X

Może bajty w "pakietach"?
pierwszy bajt - id pakietu (zakładając, że masz ich tylko 256 różnych :P)
kolejne w zależności od id...
dla przykładu update pozycji..
1 bajd - id pakietu
2 bajty - id gracza
2 bajty - pozycja x
2 bajty - pozycja y
razem 7 bajtów.

0

Zdaję sobie sprawę z tego, że przesyłam za dużo zbędnych danych. Aczkolwiek wydaje mi się, że nie powinienem tego odczuć testując aplikację lokalnie. Nie mniej jednak mam opóźnienia(lagi) podczas przesuwania obiektu, ale jestem przekonany, że wynikają one z nieprzemyślanych rozwiązań, (na które właśnie przyszła pora, aby poprawić).

Keraj napisał(a)

Może bajty w "pakietach"?
pierwszy bajt - id pakietu (zakładając, że masz ich tylko 256 różnych :P)
kolejne w zależności od id...
dla przykładu update pozycji..
1 bajd - id pakietu
2 bajty - id gracza
2 bajty - pozycja x
2 bajty - pozycja y
razem 7 bajtów.

Z tego, co zrozumiałem to radzisz abym zamiast obiektu string użył, (primitywa) byte jednak nie do końca rozumiem jak miałbym coś takiego wysłać (jak wyglądałaby taka wiadomość).
Jeżeli masz ochotę to wyjaśnij ;) może nie rozumiem sformułowania

Keraj napisał(a)

"Może bajty w "pakietach"?".

0

Ja bym zrobił Enumy z typami wysyłanych i odbieranych wiadomości (tzn jeden wspólny Enum lub dwa osobne) oraz użył Google Protocol Buffers.

Teraz wiadomośc może mieć postać:

  • int = enumType.ordinal();
  • int = bufferLength = generatedMessage().getSerializedSize();
  • byte[] = generatedMessage().writeTo(OutputStream) albo generatedMessage().toByteArray();

Protocol Buffers same w sobie nie przesyłają ani identyfikatora wiadomości, ani typów składowych, ani rozmiaru wiadomości. Same surowe dane. Mimo to umożliwiają rozszerzanie typów danych (tzn np dodawanie składowych do wiadomości) w sposób mocno nieinwazyjny. Wydajność kodowania i dekodowania jest dobra (dziesiątki megabajtów na sekundę na zwykłym kompie).

Przy używaniu Protocol Buffers dodanie nowego typu wiadomości w zasadzie ogranicza się do napisania nowego króciutkiego pliku .proto. Dzięki temu że de/ serializacją zajmuje się osobna biblioteka jest mniej okazji do popełnienia błędu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1