Zignoruj czas reakcji. W sieci LAN ping jest nieznaczny. W Internecie 60-100 ms w obie strony jest błogosławieństwem. Módlcie się do bogów lagów, abyście nie dostali skoków> 3K. Twoje oprogramowanie musiałoby działać z bardzo małą liczbą aktualizacji / s, aby mógł to stanowić problem. Jeśli wykonujesz zdjęcia z szybkością 25 aktualizacji / s, masz maksymalnie 40 ms pomiędzy otrzymaniem pakietu a działaniem na nim. I to jest jednowątkowa obudowa ...
Zaprojektuj swój system pod kątem elastyczności i poprawności. Oto mój pomysł na podłączenie podsystemu sieciowego do kodu gry: Wiadomości. Rozwiązaniem wielu problemów może być „przesyłanie wiadomości”. Myślę, że wiadomości wyleczyły raka u szczurów laboratoryjnych. Wiadomości oszczędzają mi 200 USD lub więcej na moim ubezpieczeniu samochodu. Ale poważnie, przesyłanie wiadomości jest prawdopodobnie najlepszym sposobem na dołączenie dowolnego podsystemu do kodu gry przy jednoczesnym utrzymaniu dwóch niezależnych podsystemów.
Wiadomości należy używać do wszelkiej komunikacji między podsystemem sieciowym a silnikiem gry oraz w tym przypadku między dowolnymi dwoma podsystemami. Przesyłanie komunikatów między podsystemami może być proste jak kropla danych przekazywanych przez wskaźnik za pomocą std :: list.
Wystarczy mieć kolejkę wiadomości wychodzących i odniesienie do silnika gry w podsystemie sieciowym. Gra może zrzucać wiadomości, które chce wysłać do kolejki wychodzącej, i automatycznie wysyłać je automatycznie, a może po wywołaniu funkcji „flushMessages ()”. Jeśli silnik gry ma jedną dużą, współdzieloną kolejkę komunikatów, wówczas wszystkie podsystemy, które musiały wysyłać wiadomości (logika, sztuczna inteligencja, fizyka, sieć itp.), Mogą zrzucić do niej wszystkie wiadomości, w których główna pętla gry może następnie odczytać wszystkie wiadomości i działaj odpowiednio.
Powiedziałbym, że uruchamianie gniazd w innym wątku jest w porządku, choć nie jest wymagane. Jedynym problemem związanym z tym projektem jest to, że jest on generalnie asynchroniczny (nie wiadomo dokładnie, kiedy pakiety są wysyłane) i może to utrudnić debugowanie i sprawić, że problemy związane z czasem pojawią się / znikną losowo. Mimo to, jeśli wykonane prawidłowo, żadne z nich nie powinno stanowić problemu.
Z wyższego poziomu powiedziałbym osobne połączenie sieciowe z samym silnikiem gry. Silnik gry nie dba o gniazda ani bufory, dba o zdarzenia. Zdarzenia to takie rzeczy, jak „Gracz X oddał strzał” „Wybuch w grze T”. Mogą być one interpretowane bezpośrednio przez silnik gry. Nie ma znaczenia, skąd są generowane (skrypt, działanie klienta, odtwarzacz AI itp.).
Jeśli traktujesz swój podsystem sieciowy jako sposób wysyłania / odbierania zdarzeń, zyskujesz szereg korzyści w porównaniu z wywoływaniem recv () na gnieździe.
Można na przykład zoptymalizować przepustowość, biorąc na przykład 50 małych wiadomości (o długości 1-32 bajtów), a podsystem sieciowy pakuje je w jeden duży pakiet i wysyła. Może to skompresuje je przed wysłaniem, jeśli to była wielka sprawa. Z drugiej strony kod może ponownie rozpakować / rozpakować duży pakiet do 50 dyskretnych zdarzeń, aby silnik gry mógł go odczytać. Wszystko to może odbywać się w przejrzysty sposób.
Inne fajne rzeczy to tryb gry dla jednego gracza, który ponownie wykorzystuje kod sieci, mając czystego klienta + czysty serwer działający na tej samej maszynie, komunikujący się za pośrednictwem wiadomości w pamięci współdzielonej. Następnie, jeśli Twoja gra dla pojedynczego gracza działa poprawnie, działałby również zdalny klient (tj. Prawdziwy multiplayer). Ponadto zmusza Cię do rozważenia z wyprzedzeniem, jakie dane są potrzebne klientowi, ponieważ gra dla jednego gracza wyglądałaby dobrze lub byłaby całkowicie błędna. Miksuj i dopasowuj, uruchamiaj serwer ORAZ zostań klientem w grze wieloosobowej - wszystko działa równie łatwo.