Skocz do zawartości

Gry multiplayer - struktury wysyłania danych


Rekomendowane odpowiedzi

Ostatnio interesuje się robieniem gierek z opcją multi. Jedyny w języku polskim poradnik networingu od podstaw do GMS jaki znalazłem to ten od Piotrka(dzięki wielkie piotrek:)). Jednak przy nauce zaczęła mnie interesować jedna kwestia - jak wysyłane są zmienne i które. Teoretycznie wiem, chodzi mi o kwestie czysto praktyczne. Jak to powinienem robić? Mogę sam rozkminiać ale wiadomo, że i tak po kilku grach zrozumiem coś o co mogłem od razu zapytać.

 

Wpadł mi pomysł by serwer symulował całą sytuację. Tzn.: Serwer zawiera te same obiekty co klienty i odbiera każdą zmienną i przypisuje do każdego obiektu. Wpadł mi pomysł, żeby odbywało się to na zasadzie odbierania kolejnych zmiennych i ID obiektów które tę zmienną muszą zawietać. NP.: pierwsza zmienna to ID, druga to nazwa zmiennej, lub jakiś jej numer itp., a trzecia wartość.

N.p.:

(23321) Hp 13

(21323) Dmg 1

I tak dalej... Jednak, czy serwer powinien zawierać wszystkie te obiekty? I problem #2, przecież obiekt w serwerze i w kliencie, lub w innym kliencie mogą mieć inne ID(to bardzo prawdopodobne) i w ten sposób Gracz1 dostanie hp Gracza2 i na odwrót. Rozumiecie o co chodzi? Mógłbym robić własny system przyznawania ID według innych kryteriów, ale czy to ma sens? Czy tak to powinno być? Przesyłać prędkości, hp itp? Drugi pomysł to lekka ewolucja, czyli zamiast odtwarzania każdego obiektu to odbierać zmienne, zapisywać je do tablic będących takimi "protezami obiektu" np.: oPlayer[iD obiektu, numer zmiennej(np.: Hp to 0, Speed to 1 itp.)=wartość. Jednak to za wiele nie zmienia, a jedynie obiektów na serwerze będzie mniej :/

Może powinienem przesyłać jedynie to co jest w danej chwili nie zbędne(musowo pozycje graczy i npcetów, i np hp jedynie gracza którego atakujemy, nie potrzebujemy wiedzieć ile hp ma inny gracz, skoro z nim nie walczymy). Jednak to rodzi kolejne pytania. Np.: Jak zorganizować przesył pakietów, by każdy klient mógł żądać od serwera tylko to co potrzebuje?

Dlatego wydaje mi się, że w złą stronę myślę :/ Możecie mi powiedzieć jak Wy to robicie?

Bo niestety, ale szybko zrozumiałem, że umiejętność wysyłania zmiennych do innych klientów przez serwer to nie wszystko :/

Odnośnik do komentarza
Udostępnij na innych stronach

Jest jedna prosta zasada której używa w zasadzie każdy.

 

Kiedy wysyłasz pakiet, ZAWSZE zawiera on nagłówek który ZAWSZE jest w tym samym formacie. (np. u8 lub u16)

Wartość tego nagłówka określa co jest w środku.

 

Np. jak jest w nim 0 to wysłanie nicku

1 - wystrzelenie naboju

itd itp... Pamiętam, że kiedyś zrobiłem o tym sporą wiadomość, musi gdzieś się walać w zaawansowanych

 

Edit: Dobra jakos znalezc nie moge

Odnośnik do komentarza
Udostępnij na innych stronach

Robiłem parę gier multiplayer, żeby z kolegami pograć (ale na 39dll). Miałem to zorganizowane tak.

Po wejściu na serwer dostajemy od serwera ID, a pod naszym ID w tablicy globalnej player, był socket, czy jak się to tam zwało. Informacje wysyłałem tak

GML
czyszczę_bufer();

short_wysłanie(0);

int_wysłanie(moje_id);

int_wysłanie(x);

int_wysłanie(y);

//short i int, w sensie, że różne te wielkości. Mam nadzieję, że wiesz co mam na myśli, bo nie wiem jak to powiedzieć</span>

A odbierałem w ten sposób

GML
switch( odebranie(short) )

{

case 0:

var i_id=odebranie(int);

global.player[i_id].x=odebranie(int);

global.player[i_id].y=odebranie[int);

break;

}

Zrobiłem sobie kiedyś skrypt który wyglądał tak: wysłanie(naglowek_wiadomosci, wiad1, wiad2, wiad3); A ogólnie to sprawdzałem ilość podanych argumentów i wtedy dopiero odbierałem je, bo były problemy. Mi tam taki sposób wysyłania i odbierania informacji bardzo pasował ;3

Odnośnik do komentarza
Udostępnij na innych stronach

Dobra dzięki Wam wielkie, szczególnie Tobie Sutikku, jak tylko znajdę chwilę to się tym pobawię i ew. będę pytał dalej :)

@e: A co z npcetami? Powinienem każdemu graczu wysyłać dane o każdym npcecie? I jak określić którego npceta dane przestyłam? Bo gracz ma swój socket, czy coś tam i jest łatwo, ale npcety mają IDi niby, ale u każdego gracza każdy obiekt może mieć inne ID(bo GMS chyba nadaje ID w kolejności tworzenia obiektów) :/

Powinienem rozumie zrobić własny system nadawania ID? I powinien każdy gracz otrzymywać info o każdym npc, czy tylko jakoś "pytać" serwer o tego, którego aktualnie ma na celowniku, a o reszcie wiedzieć tylko gdzie się znajdują?

Odnośnik do komentarza
Udostępnij na innych stronach

Ja z takimi ruchomymi obiektami, też miałem listę. A u graczy to już jako obiekty. Tylko, że u mnie to były stworki które się od czasu do czasu pojawiały. Przy pojawianiu wysyłałem informację, gdzie się pojawia i ID tego stworka na serwerze. Jakoś tak

GML
var iid=nastepne_id_w_kolei

var global.npc[iid]=instance_create(random(1024), random(1024, obj_npc);

czyszcze_bufor();

wysłanie_short(1);

wysłanie_int(iid);

wysłanie_int(global.npc[iid].x);

wysłanie_int(global.npc[iid].y);

Gdzieś czytałem, że powinno się wszystko obliczać itd. na serwerze, ale ja zadawane obrażenia, po prostu wysyłałem do serwera (przypominam, że się ponoć nie powinno tak robić, zależy w sumie). Wysyłałem wtedy ID npc który został uderzony, a przy odbieraniu, wysyłałem informację do reszty graczy z serwera, że ten npc został uderzony, więc u nich ten NPC z tym ID straci to HP.

A właśnie. Ja na serwerze lubiłem robić obiekty, bo z serwera miałem podgląd na to, co się dzieje w grze. Zamiast tego możesz zrobić tablicę dwuwymiarową oczywiście.

Odnośnik do komentarza
Udostępnij na innych stronach

No fakt, że jest podgląd, ale łatwiej postawić serwer skoro będzie mniej wymagający, a do podglądu można zrobić jakiś specjalny klient do podglądu :) A jakieś kwestie odnośnie zabezpieczeń są? Jak rozwiązać problem speed cheatu itp.?

Odnośnik do komentarza
Udostępnij na innych stronach

Hmm. Bo, generalnie, zamiast wysyłać swoje pozycję co ruch, przewiduje się ruchy. W przykładzie networkingu dołączonego do gms, wysyłane są informacje o wciśnięciu klawisza. A serwer oblicza o ile ma nasz pan (ew. pani) się przesunąć. Dlatego też jak najwięcej serwer powinien ogarniać.

Odnośnik do komentarza
Udostępnij na innych stronach

Hmm. Bo, generalnie, zamiast wysyłać swoje pozycję co ruch, przewiduje się ruchy. W przykładzie networkingu dołączonego do gms, wysyłane są informacje o wciśnięciu klawisza. A serwer oblicza o ile ma nasz pan (ew. pani) się przesunąć. Dlatego też jak najwięcej serwer powinien ogarniać.

No rzeczywiście widziałem coś takiego na jakimś przykładzie, jeszcze pod 39dll. Bardzo cenna uwaga, bo właśnie wolę wcześniej wiedzieć takie rzeczy, niż pisać grę, a potem przepisywać ją od nowa, bo okaże się, że pominąłem bardzo ważne kwestie. Jest jeszcze jakaś zasada odnośnie pisania gier multi o której powinienem wiedzieć? Alarmy też rozumiem, że powinien serwer odmierzać? Czy powinienem także odliczać czas na podstawie godziny pobieranej z serwera, czy to spowoduje więcej problemów niż zalet? I są jakieś istotne uwagi na temat optymalizacji serwera? Czytałem gdzieś, że należy ustalać priorytety danych pakietów i te istotniejsze wysyłać częściej, a ten nie istotne rzadko. A więc te najistotniejsze jak pozycja powinienem wysyłać co step(w tym wypadku 60/s) czy raczej nawet takie dane rzadziej? I jak często np.: wysyłać info o wciskanych klawiszach(bo rozumiem, że nie wysyłam kiedy zostanie wciśnięty i kiedy puszczony, a czy jest aktualnie wciśnięty? W innym razie co jeśli nastąpi lag w chwili puszczania i serwer nie wychwyci tego)?

A może serwer powinien niektóre informację potwierdzać, czy dostał?

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ę...