Autor Wątek: Gra MMO  (Przeczytany 984 razy)

Offline mukai

  • Użytkownik

# Lipiec 28, 2011, 19:02:38
Mam w planie napisanie prostej gry karcianej online. Nie chodzi mi o grę w pokera czy tym podobne ale coś w stylu Magic: the Gathering. Dla nie wtajemniczonych chodzi o to, że gracz zakłada konto dostaje jakieś tam punkty i za te punkty kupuje karty z tych kart składa talie a następnie przy jej użyciu gra z innym graczami, zdobywa punkty, doświadczenie, lvl, kupuje nowe karty, ulepsza stare lub składa nowe talie i tak dalej. Od początku zdawałem sobie sprawę, że nie jest to takie łatwe jak by się mogło wydawać ale im dłużej się nad tym wszystkim zastanawiam tym więcej pytań się pojawia. Nie chce się brać za kodowanie zanim wszystkiego sobie nie poukładam i nie zaprojektuje dlatego chcę Was zapytać o zdanie w kilku kwestiach.

1. Oczywiste jest, że wszystkie dane i statystyki konta będą przechowywane w bazie danych. Zastanawiam się co powinien z tymi informacjami robić serwer kiedy gracz się zaloguje.
    Pierwszy pomysł był taki aby w aplikacji serwera zaimplementować klasę gracz i po zalogowaniu wczytać do niej wszystkie informacje danego gracza i dodać go do listy zalogowanych graczy. Po wylogowaniu informacje w bazie danych były by uaktualniane. Zastanawiam się jednak czy takie rozwiązanie nie pochłonie zbyt wiele pamięci na serwerze kiedy zalogowanych graczy zacznie przybywać. Kolejnym problemem jest utrata danych w przypadku niespodziewanego wyłączenia się serwera chociaż temu można by częściowo zapobiec na przykład uaktualniając bazę danych co załóżmy 10 minut.
    Kolejnym pomysłem jest operowanie bezpośrednio na bazie danych czyli za każdym razem gdy jakaś informacja jest potrzebne była by ona pobierana z bazy danych oraz w przypadku jakiejkolwiek zmiany baza była by od razu uaktualniana. Rozwiązało by to problem utraty danych oraz ilości potrzebnej pamięci ale zastanawiam się czy przy kilkudziesięciu lub kilkuset graczach taka baza danych dała by radę wyrobić?

2. Zastanawia mnie czy dobrym rozwiązaniem jest weryfikowanie niektórych informacji po stronie klienta. Na przykład gracz chce kupić kartę za ileś tam punktów. Trzeba sprawdzić czy posiada wystarczająca liczbę punktów. Aplikacja klienta wie ile punktów ma gracz oraz ile kosztuje karta ponieważ obie te informacje są gdzieś tam wyświetlane. Można więc sprawdzić czy gracz może kupić kartę czy nie. Jeśli może, wystarczy wysłać informację do serwera, że gracz kupił kartę.
    Drugi sposób to wysłanie do serwera informacji o tym, że gracz chce kupić kartę, zweryfikowanie tego przez serwer i wysłanie odpowiedniej wiadomości z powrotem do klienta.
    To jest tylko jeden przykład ale podobnych sytuacji będzie bardzo dużo. Dlatego pierwszy sposób wydaje mi się lepszy ponieważ znacznie odciąży serwer i zmniejszy ilość przesyłanych danych. Jedna rzecz mnie zastanawia. Czy taki sposób jest bezpieczny? Nigdy nie oszukiwałem w grach komputerowych więc się na tym nie znam ale czy ktoś kto się zna będzie mógł w jakiś sposób zmienić przechowywane w aplikacji klienta dane? Na przykład zwiększyć ilość punktów czy zmniejszyć ceny albo wpłynąć na wysyłane do serwera dane?

3. Ostatnia sprawa jaka mnie nurtuję to czy serwer powinien pilnować rozgrywki czy ma on tylko pośredniczyć w wymianie informacji? Chodzi o to czy logika gry i wszystkie zasady powinny być zaimplementowane po stronie serwera i to on będzie nadzorował rozgrywkę czy po stronie klienta? Załóżmy, że gracz zagrywka kartę której nie może zagrać w danym momencie. Jeśli zasady gry są po stronie klienta aplikacja od razu sprawdzi czy takie zagranie jest możliwe czy nie. Jeśli jest to wyśle do drugiego gracza za pośrednictwem serwera informację o tym, że zagrał kartę. Jeśli to serwer weryfikuje cała rozgrywkę to gracz musi wysłać informacje o tym, że chce zagrać kartę, następnie serwer sprawdzi czy może to zrobić. Jeśli tak to wyśle do obu graczy informację o zagraniu karty.  Weryfikowanie zasad przez klienta byłoby zdecydowanie szybsze i znacznie odciąży serwer. Co prawda w takiej grze nie przesyła się bardzo dużo danych ale nie chcę żeby się okazało, że przy 200 graczach i 100 grach serwer przestaje wyrabiać. Pytanie czy sprawdzanie logiki gry po stronie klienta jest bezpieczne i czy ktoś kto się na tym zna nie będzie w stanie oszukiwać?

    Wybaczcie, że się tak rozpisałem ale chciałem wszystko dokładnie wyjaśnić, żeby nie było żadnych wątpliwości. Czekam na wszelkie pomysły i sugestie. Jeśli macie jakieś materiału, tutoriale lub cokolwiek co może mi pomóc to będę wdzięczny.   

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Kos

  • Użytkownik
    • kos.gd

# Lipiec 28, 2011, 19:12:47
Cytuj
Pierwszy pomysł był taki aby w aplikacji serwera zaimplementować klasę gracz i po zalogowaniu wczytać do niej wszystkie informacje danego gracza i dodać go do listy zalogowanych graczy. Po wylogowaniu informacje w bazie danych były by uaktualniane.

Do wygooglania: Object Relational Mapping :), na każdą platformę jest od metra frameworków robiących to za Ciebie. Piszesz klasy, automat Ci generuje z klas schemat bazy danych i tworzy tabelki. Operujesz na klasach, automat Ci je uaktualnia z bazą. Nie jest to ofc takie banalne (jest dużo zawiłości, doświadczenie z bazami danych mile widziane), ale do ogarnięcia.

Cytuj
. Zastanawia mnie czy dobrym rozwiązaniem jest weryfikowanie niektórych informacji po stronie klienta.

Tak, ponieważ oszczędza transfer i daje graczowi szybszą odpowiedź. Nie, ponieważ nie jest bezpieczne, bo gracz może sfabrykować sobie dowolną komunikację między serwerem a klientem/przeglądarką. Morał: walidacja po stronie serwera wszędzie + walidacja po stronie klienta wszędzie gdzie jest sens (i gdzie Ci się chce).

Cytuj
Ostatnia sprawa jaka mnie nurtuję to czy serwer powinien pilnować rozgrywki czy ma on tylko pośredniczyć w wymianie informacji? Chodzi o to czy logika gry i wszystkie zasady powinny być zaimplementowane po stronie serwera i to on będzie nadzorował rozgrywkę czy po stronie klienta?

Huh, da się to zrobić na 2 sposoby:
a) serwer jest faktycznie "serwerem" (tak jest we wszystkich grach MMO jakie widziałem),
b) serwer jest "lobby do dobierania graczy", a po dobraniu jeden z graczy staje się serwerem. Tak się ongiś grało w gry po sieci LAN. Rozwiązanie ofc nie jest bezpieczne, bo gracz-serwer może robić co chce, ale zaoszczędzi Twojemu serwerowi 90% zasobów. Jest też bardziej problematyczne w implementacji i ma 10 innych wad.

Offline iniside

  • Użytkownik

# Lipiec 28, 2011, 19:43:47
Kiedyś coś podobnego kodziłem, niewiele z tego wyszło (Żeby być szczerym), ale troche doświadczeń zostało.

Cytuj
1. Oczywiste jest, że wszystkie dane i statystyki konta będą przechowywane w bazie danych. Zastanawiam się co powinien z tymi informacjami robić serwer kiedy gracz się zaloguje.
Absolutnie nic. Dane wyciągasz z bazy danych kiedy są ci potrzebne.

Cytuj
Kolejnym pomysłem jest operowanie bezpośrednio na bazie danych czyli za każdym razem gdy jakaś informacja jest potrzebne była by ona pobierana z bazy danych oraz w przypadku jakiejkolwiek zmiany baza była by od razu uaktualniana. Rozwiązało by to problem utraty danych oraz ilości potrzebnej pamięci ale zastanawiam się czy przy kilkudziesięciu lub kilkuset graczach taka baza danych dała by radę wyrobić?
Dałaby rade. Nowoczesne bazy danych automatycznie cachują dana. Jeśli od ostatniego odczytu nie zaszły żadne zmiany to poprostu są pobierane z cache. Pozatym róźne ORMy też cachują dane, żeby uniknąć zbyt wielu zapytań, no i w końcu można sobie samemu taki second-level caching napisać, jak wiesz jak.
Z przykładu to AFAIR GuildWars działa na SQL Server.
Do tego pomsyłu idealnie pasuje baza NoSQL. Np. MongoDB.

Ogólnie ujme to w ten sposob. Przechowywanie danych to twój najmniejszy problem w tej chwili. Przede wszystkim skup się na napisaniu samego servera który te rozgrywke będzie obsługiwał.

Cytuj
Zastanawia mnie czy dobrym rozwiązaniem jest weryfikowanie niektórych informacji po stronie klienta.
Absolutnie nie. Wszystkie informacje dotyczące przebiegu gry powinny być weryfikowane przez server.
Każda weryfikacja po stronie klienta to potencjalny exploit.

Cytuj
Ostatnia sprawa jaka mnie nurtuję to czy serwer powinien pilnować rozgrywki czy ma on tylko pośredniczyć w wymianie informacji?
Nie ma jednoznacznie odpowiedzi. Możesz zrobić typowy klient-server, w który server pilnuje graczy i zajmuje się kompleksową obsługą gry (czyli tak jak w każdym MMO), albo zrobić P2P, z tym, że i tak jakiś gracz musi być serverem. Pierwsze rozwiązanie jest prostsze i pewniejsze.

Ogólnie zasada jest prosta. Informacje dotyczące przebiegu rozgrywki powinny być weryfikowane przez server. Nie jestem pewny czy w tym przypadku nawet jest sens implementować weryfikacje po stronie klienta, po dane i tak będą musiały być przesłane na serwer i weryfikowane ponowanie.
Inne mniej newlargiczne rzeczy mogą byc sprawdzane po stronie klienta.

Podsumowujac. Wydajność jest ostatnią rzecz o jaką należy się martwić. Najpierw doprowadzaź do stanu w którym da się grać, a potem pomyśl, co robić aby było szybciej.