Başlayanlar üçün oyunlarda şəbəkə modeli haqqında

Başlayanlar üçün oyunlarda şəbəkə modeli haqqında
Son iki həftə ərzində oyunum üçün onlayn mühərrik üzərində işləyirəm. Bundan əvvəl oyunlarda şəbəkələşmə haqqında heç nə bilmirdim, ona görə də bütün anlayışları başa düşmək və öz şəbəkə mühərrikimi yaza bilmək üçün çoxlu məqalələr oxudum və çoxlu təcrübələr etdim.

Bu təlimatda mən sizinlə öz oyun mühərrikinizi yazmadan əvvəl öyrənməli olduğunuz müxtəlif anlayışları, həmçinin onları öyrənmək üçün ən yaxşı resursları və məqalələri bölüşmək istərdim.

Ümumiyyətlə, şəbəkə arxitekturasının iki əsas növü var: peer-to-peer və müştəri-server. Peer-to-peer (p2p) arxitekturasında məlumatlar hər hansı birləşdirilmiş oyunçu cütləri arasında ötürülür, müştəri-server arxitekturasında isə məlumatlar yalnız oyunçular və server arasında ötürülür.

Bəzi oyunlarda peer-to-peer arxitekturası hələ də istifadə olunsa da, müştəri-server standartdır: onu həyata keçirmək daha asandır, daha kiçik kanal eni tələb edir və fırıldaqdan qorunmağı asanlaşdırır. Buna görə də, bu dərslikdə biz müştəri-server arxitekturasına diqqət yetirəcəyik.

Xüsusilə, bizi ən çox avtoritar serverlər maraqlandırır: belə sistemlərdə server həmişə haqlıdır. Məsələn, əgər oyunçu özünün koordinatlarda olduğunu düşünürsə (10, 5) və server ona (5, 3) olduğunu söyləyirsə, müştəri öz mövqeyini vitse ilə deyil, serverin bildirdiyi ilə əvəz etməlidir. əksinə. Nüfuzlu serverlərdən istifadə fırıldaqçıları müəyyən etməyi asanlaşdırır.

Şəbəkə oyun sistemləri üç əsas komponentdən ibarətdir:

  • Nəqliyyat protokolu: verilənlərin müştərilər və server arasında necə ötürülməsi.
  • Tətbiq protokolu: müştərilərdən serverə və serverdən müştərilərə nə və hansı formatda ötürülür.
  • Tətbiq məntiqi: ötürülən məlumatların müştərilərin və serverin vəziyyətini yeniləmək üçün necə istifadə edildiyi.

Hər bir hissənin rolunu və onlarla əlaqəli problemləri anlamaq çox vacibdir.

Nəqliyyat protokolu

İlk addım server və müştərilər arasında məlumatların daşınması üçün protokol seçməkdir. Bunun üçün iki İnternet protokolu var: TCP и UDP. Lakin siz onlardan biri əsasında öz nəqliyyat protokolunuzu yarada və ya onlardan istifadə edən kitabxanadan istifadə edə bilərsiniz.

TCP və UDP müqayisəsi

Həm TCP, həm də UDP-ə əsaslanır IP. IP paketin mənbədən alıcıya ötürülməsinə imkan verir, lakin göndərilən paketin gec-tez alıcıya çatacağına, ən azı bir dəfə çatacağına və paketlərin ardıcıllığının düzgün şəkildə çatacağına zəmanət vermir. sifariş. Üstəlik, bir paket yalnız dəyərlə verilən məhdud miqdarda məlumat ehtiva edə bilər MTU.

UDP sadəcə IP-nin üstündəki nazik təbəqədir. Buna görə də eyni məhdudiyyətlərə malikdir. Bunun əksinə olaraq, TCP bir çox xüsusiyyətlərə malikdir. Səhv yoxlanışı ilə iki qovşaq arasında etibarlı, nizamlı əlaqə təmin edir. Beləliklə, TCP çox rahatdır və bir çox digər protokollarda istifadə olunur, məsələn. HTTP, FTP и SMTP. Ancaq bütün bu xüsusiyyətlər bir qiymətə gəlir: gecikmə.

Bu funksiyaların niyə gecikməyə səbəb ola biləcəyini başa düşmək üçün TCP-nin necə işlədiyini başa düşməliyik. Göndərən qovşaq paketi qəbul edən qovşağa ötürəndə o, təsdiq (ACK) almağı gözləyir. Müəyyən bir müddətdən sonra onu qəbul etmirsə (paket və ya təsdiq itirildiyinə görə və ya başqa səbəbə görə), o zaman paketi yenidən göndərir. Üstəlik, TCP paketlərin düzgün ardıcıllıqla qəbul edilməsinə zəmanət verir, buna görə də itirilmiş paket alınana qədər bütün digər paketlər, hətta qəbul edən host tərəfindən qəbul edilmiş olsa belə, emal edilə bilməz.

Ancaq yəqin ki, təsəvvür edə bildiyiniz kimi, multiplayer oyunlarda gecikmə çox vacibdir, xüsusən də FPS kimi hərəkətlərlə dolu janrlarda. Buna görə bir çox oyun UDP-ni öz protokolu ilə istifadə edir.

Doğma UDP əsaslı protokol müxtəlif səbəblərə görə TCP-dən daha səmərəli ola bilər. Məsələn, bəzi paketləri etibarlı, digərlərini isə etibarsız kimi qeyd edə bilər. Buna görə də, etibarsız paketin alıcıya çatıb-çatmayacağının əhəmiyyəti yoxdur. Və ya bir axındakı itirilmiş paketin qalan axınları ləngitməməsi üçün birdən çox məlumat axını emal edə bilər. Məsələn, oyunçunun daxil edilməsi üçün mövzu və söhbət mesajları üçün başqa bir başlıq ola bilər. Təcili olmayan söhbət mesajı itərsə, o, təcili olan girişi yavaşlatmayacaq. Və ya xüsusi protokol, video oyun mühitində daha səmərəli olmaq üçün etibarlılığı TCP-dən fərqli şəkildə həyata keçirə bilər.

Beləliklə, əgər TCP bu qədər əmilirsə, biz UDP əsasında öz nəqliyyat protokolumuzu yaradacağıq?

Bir az daha mürəkkəbdir. TCP oyun şəbəkəsi sistemləri üçün demək olar ki, suboptimal olsa da, xüsusi oyununuz üçün kifayət qədər yaxşı işləyə və qiymətli vaxtınıza qənaət edə bilər. Məsələn, növbəyə əsaslanan oyun və ya yalnız LAN şəbəkələrində oynana bilən oyun üçün gecikmə problemi olmaya bilər, burada gecikmə və paket itkisi İnternetdən xeyli aşağıdır.

World of Warcraft, Minecraft və Terraria da daxil olmaqla bir çox uğurlu oyunlar TCP-dən istifadə edir. Bununla belə, əksər FPS-lər öz UDP əsaslı protokollarından istifadə edirlər, ona görə də aşağıda onlar haqqında daha çox danışacağıq.

TCP-dən istifadə etmək qərarına gəlsəniz, onun söndürüldüyünə əmin olun Nagle alqoritmi, çünki göndərilməzdən əvvəl paketləri bufer edir, yəni gecikmə müddətini artırır.

Çox oyunçulu oyunlar kontekstində UDP və TCP arasındakı fərqlər haqqında daha çox öyrənmək üçün Glenn Fiedlerin məqaləsini oxuya bilərsiniz. UDP vs. TCP.

Öz protokolu

Beləliklə, siz öz nəqliyyat protokolunuzu yaratmaq istəyirsiniz, lakin haradan başlayacağınızı bilmirsiniz? Bəxtiniz gətirdi, çünki Glenn Fiedler bu barədə iki heyrətamiz məqalə yazıb. Onlarda çoxlu ağıllı fikirlər tapa bilərsiniz.

Birinci məqalə Oyun Proqramçıları üçün Şəbəkə 2008, ikincidən daha asan, Oyun Şəbəkəsi Protokolunun qurulması 2016. Mən sizə köhnəsindən başlamağı məsləhət görürəm.

Qeyd edək ki, Glenn Fiedler UDP-yə əsaslanan xüsusi protokoldan istifadənin böyük tərəfdarıdır. Və onun məqalələrini oxuyandan sonra, yəqin ki, onun TCP-nin video oyunlarında ciddi çatışmazlıqlar olması fikrini qəbul edəcək və öz protokolunuzu həyata keçirmək istəyəcəksiniz.

Ancaq şəbəkədə yenisinizsə, özünüzə yaxşılıq edin və TCP və ya kitabxanadan istifadə edin. Öz nəqliyyat protokolunuzu uğurla həyata keçirmək üçün əvvəlcədən çox şey öyrənməlisiniz.

Şəbəkə kitabxanaları

Əgər TCP-dən daha səmərəli bir şeyə ehtiyacınız varsa, lakin öz protokolunuzu həyata keçirmək və bir çox təfərrüata varmaq kimi əngəldən keçmək istəmirsinizsə, şəbəkə kitabxanasından istifadə edə bilərsiniz. Onların bir çoxu var:

Mən onların hamısını sınamamışam, lakin istifadəsi asan və etibarlı olduğu üçün ENet-ə üstünlük verirəm. Bundan əlavə, aydın sənədlərə və yeni başlayanlar üçün təlimata malikdir.

Nəqliyyat Protokolu: Nəticə

Xülasə etmək üçün: iki əsas nəqliyyat protokolu var: TCP və UDP. TCP bir çox faydalı xüsusiyyətlərə malikdir: etibarlılıq, paket sifarişinin qorunması, səhvlərin aşkarlanması. UDP-də bütün bunlar yoxdur, lakin TCP öz təbiətinə görə gecikmə müddətini artırıb, bu da bəzi oyunlar üçün qəbuledilməzdir. Yəni, aşağı gecikmə müddətini təmin etmək üçün siz UDP əsasında öz protokolunuzu yarada və ya UDP-də nəqliyyat protokolunu həyata keçirən və multiplayer video oyunları üçün uyğunlaşdırılmış kitabxanadan istifadə edə bilərsiniz.

TCP, UDP və kitabxana arasında seçim bir neçə amildən asılıdır. Birincisi, oyunun ehtiyaclarından: aşağı gecikməyə ehtiyac varmı? İkincisi, ərizə protokolunun tələblərindən: ona etibarlı protokol lazımdırmı? Növbəti hissədə görəcəyimiz kimi, etibarsız protokolun kifayət qədər uyğun olduğu bir tətbiq protokolu yaratmaq mümkündür. Nəhayət, şəbəkə mühərriki tərtibatçısının təcrübəsini də nəzərə almalısınız.

Mənim iki məsləhətim var:

  • Nəqliyyat protokolunu tətbiqin qalan hissəsindən mümkün qədər çıxarın ki, bütün kodu yenidən yazmadan asanlıqla dəyişdirilə bilsin.
  • Həddindən artıq optimallaşdırmayın. Şəbəkə mütəxəssisi deyilsinizsə və xüsusi UDP-əsaslı nəqliyyat protokoluna ehtiyacınız olub olmadığına əmin deyilsinizsə, TCP və ya etibarlılığı təmin edən kitabxana ilə başlaya, sonra performansı test edib ölçə bilərsiniz. Problemlər yaranarsa və bunun səbəbinin nəqliyyat protokolu olduğuna əminsinizsə, o zaman öz nəqliyyat protokolunuzu yaratmağın vaxtı gələ bilər.

Bu hissənin sonunda oxumağınızı tövsiyə edirəm Multiplayer Oyun Proqramlaşdırmasına Giriş burada müzakirə olunan bir çox mövzuları əhatə edən Brian Hook tərəfindən.

Tətbiq protokolu

İndi müştərilər və server arasında məlumat mübadiləsi apara bildiyimiz üçün hansı məlumatların və hansı formatda ötürüləcəyinə qərar verməliyik.

Klassik sxem müştərilərin giriş və ya hərəkətləri serverə göndərməsidir və server cari oyun vəziyyətini müştərilərə göndərir.

Server tam vəziyyəti deyil, pleyerin yaxınlığında yerləşən obyektlərlə süzülmüş vəziyyəti göndərir. O, bunu üç səbəbdən edir. Birincisi, tam dövlət yüksək tezlikdə ötürülmək üçün çox böyük ola bilər. İkincisi, müştərilər əsasən vizual və audio məlumatlarla maraqlanırlar, çünki oyun məntiqinin çox hissəsi oyun serverində simulyasiya olunur. Üçüncüsü, bəzi oyunlarda oyunçu müəyyən məlumatları, məsələn, düşmənin xəritənin digər tərəfindəki mövqeyini bilməməlidir, əks halda paketləri iyləyə bilər və onu öldürmək üçün hara hərəkət edəcəyini dəqiq bilir.

Serializasiya

İlk addım göndərmək istədiyimiz məlumatları (giriş və ya oyun vəziyyəti) ötürülməyə uyğun formata çevirməkdir. Bu proses adlanır serializasiya.

Dərhal ağlına gələn fikir, JSON və ya XML kimi insan tərəfindən oxuna bilən formatdan istifadə etməkdir. Ancaq bu, tamamilə təsirsiz olacaq və kanalın çox hissəsini boşa çıxaracaq.

Bunun əvəzinə daha yığcam olan ikili formatdan istifadə etmək tövsiyə olunur. Yəni paketlər yalnız bir neçə baytdan ibarət olacaq. Burada nəzərə alınmalı bir problem var bayt sırası, müxtəlif kompüterlərdə fərqli ola bilər.

Məlumatları seriallaşdırmaq üçün kitabxanadan istifadə edə bilərsiniz, məsələn:

Kitabxananın portativ arxivlər yaratdığına və indianlığa əhəmiyyət verdiyinə əmin olun.

Alternativ bir həll onu özünüz həyata keçirməkdir; xüsusilə kodunuza məlumat mərkəzli bir yanaşma istifadə edirsinizsə, bu, xüsusilə çətin deyil. Bundan əlavə, kitabxanadan istifadə edərkən həmişə mümkün olmayan optimallaşdırmaları yerinə yetirməyə imkan verəcəkdir.

Glenn Fiedler seriallaşdırma haqqında iki məqalə yazdı: Oxuma və Yazma Paketləri и Serializasiya strategiyaları.

Sıxılma

Müştərilər və server arasında ötürülən məlumatların miqdarı kanalın bant genişliyi ilə məhdudlaşır. Məlumatların sıxılması sizə hər bir görüntüdə daha çox məlumat ötürməyə, yeniləmə tezliyini artırmağa və ya sadəcə kanal tələblərini azaltmağa imkan verəcək.

Bit qablaşdırma

Birinci texnika bit qablaşdırmadır. İstənilən dəyəri təsvir etmək üçün lazım olan bitlərin tam sayından istifadə etməkdən ibarətdir. Məsələn, 16 fərqli dəyərə malik ola bilən bir nömrəniz varsa, o zaman tam bayt (8 bit) əvəzinə sadəcə 4 bit istifadə edə bilərsiniz.

Glenn Fiedler bunun necə həyata keçiriləcəyini məqalənin ikinci hissəsində izah edir Oxuma və Yazma Paketləri.

Bit qablaşdırma, növbəti bölmənin mövzusu olacaq nümunə götürmə ilə xüsusilə yaxşı işləyir.

Nümunə götürmə

Nümunə götürmə dəyəri kodlaşdırmaq üçün mümkün dəyərlərin yalnız bir hissəsini istifadə edən itkili sıxılma texnikasıdır. Diskretləşdirməni həyata keçirməyin ən asan yolu üzən nöqtə nömrələrini yuvarlaqlaşdırmaqdır.

Glenn Fiedler (yenə də!) məqaləsində nümunə götürmənin necə həyata keçiriləcəyini göstərir Snapshot sıxılma.

Sıxılma alqoritmləri

Növbəti texnika itkisiz sıxılma alqoritmləri olacaqdır.

Budur, mənim fikrimcə, bilməli olduğunuz ən maraqlı üç alqoritmdir:

  • Huffman kodlaması son dərəcə sürətli və yaxşı nəticələr verə bilən əvvəlcədən hesablanmış kodla. Quake3 şəbəkə mühərrikində paketləri sıxışdırmaq üçün istifadə edilmişdir.
  • zlib heç vaxt məlumatın həcmini artırmayan ümumi təyinatlı sıxılma alqoritmidir. Necə görmək olar burada, müxtəlif tətbiqlərdə istifadə edilmişdir. Vəziyyətləri yeniləmək üçün lazımsız ola bilər. Lakin serverdən müştərilərə aktivlər, uzun mətnlər və ya ərazi göndərmək lazım olduqda faydalı ola bilər.
  • Sürət uzunluqlarının kopyalanması - Bu, yəqin ki, ən sadə sıxılma alqoritmidir, lakin müəyyən növ məlumatlar üçün çox effektivdir və zlib-dən əvvəl əvvəlcədən emal addımı kimi istifadə edilə bilər. Çoxlu bitişik elementlərin təkrarlandığı plitələr və ya voksellərdən ibarət ərazini sıxmaq üçün xüsusilə uyğundur.

Delta sıxılması

Son sıxılma texnikası delta sıxılmadır. Bu, yalnız cari oyun vəziyyəti ilə müştəri tərəfindən alınan son vəziyyət arasındakı fərqlərin ötürülməsindən ibarətdir.

İlk dəfə Quake3 şəbəkə mühərrikində istifadə edilmişdir. Bunun necə istifadə olunacağını izah edən iki məqalə var:

Glenn Fiedler də məqaləsinin ikinci hissəsində bundan istifadə etmişdir Snapshot sıxılma.

Şifrələmə

Bundan əlavə, müştərilər və server arasında məlumat ötürülməsini şifrələməlisiniz. Bunun bir neçə səbəbi var:

  • məxfilik/məxfilik: mesajları yalnız qəbul edən şəxs oxuya bilər və şəbəkəni iyləyən başqa heç bir şəxs onları oxuya bilməyəcək.
  • autentifikasiya: oyunçu rolunu oynamaq istəyən şəxs onun açarını bilməlidir.
  • Fırıldaqların qarşısının alınması: Zərərli oyunçular üçün öz fırıldaq paketlərini yaratmaq daha çətin olacaq, onlar şifrələmə sxemini təkrarlamalı və açarı tapmalı olacaqlar (hər əlaqə ilə dəyişir).

Bunun üçün kitabxanadan istifadə etməyi tövsiyə edirəm. istifadə etməyi təklif edirəm libsodyum, çünki o, xüsusilə sadədir və əla dərsliklərə malikdir. Xüsusilə maraqlı olan dərslikdir açar mübadiləsi, hər bir yeni əlaqə ilə yeni açarlar yaratmağa imkan verir.

Ərizə protokolu: Nəticə

Bununla bizim ərizə protokolumuz yekunlaşır. İnanıram ki, sıxılma tamamilə isteğe bağlıdır və onu istifadə etmək qərarı yalnız oyundan və tələb olunan bant genişliyindən asılıdır. Şifrələmə, mənim fikrimcə, məcburidir, lakin ilk prototipdə onsuz da edə bilərsiniz.

Tətbiq məntiqi

Biz indi müştəridəki vəziyyəti yeniləyə bilirik, lakin gecikmə ilə bağlı problemlər yarana bilər. Oyunçu, daxiletməni tamamladıqdan sonra, onun dünyaya necə təsir etdiyini görmək üçün oyun vəziyyətinin serverdən yenilənməsini gözləməlidir.

Üstəlik, iki dövlət yeniləməsi arasında dünya tamamilə statikdir. Dövlət yeniləmə dərəcəsi aşağı olarsa, hərəkətlər çox sarsıntılı olacaq.

Bu problemin təsirini azaltmaq üçün bir neçə üsul var və mən onları növbəti hissədə əhatə edəcəyəm.

Latency Hamarlaşdırma Texnikaları

Bu bölmədə təsvir edilən bütün texnikalar seriyada ətraflı müzakirə olunur Sürətli Çox Oyunçu Qabriel Qambetta. Bu əla silsiləli məqalələri oxumağı çox tövsiyə edirəm. O, həmçinin bu texnikaların praktikada necə işlədiyini görməyə imkan verən interaktiv demo təqdim edir.

Birinci texnika, serverdən cavab gözləmədən giriş nəticəsini birbaşa tətbiq etməkdir. Bu adlanır müştəri tərəfi proqnozlaşdırma. Bununla belə, müştəri serverdən yeniləmə aldıqda, onun proqnozunun düzgün olduğunu yoxlamalıdır. Əgər belə deyilsə, o zaman serverdən aldıqlarına uyğun olaraq vəziyyətini dəyişmək lazımdır, çünki server avtoritardır. Bu texnika ilk dəfə Quake-də istifadə edilmişdir. Bu barədə daha ətraflı məqalədə oxuya bilərsiniz Quake Engine kodunun nəzərdən keçirilməsi Fabien Sanqlars [tərcümə Habré haqqında].

İkinci üsullar iki dövlət yeniləməsi arasında digər obyektlərin hərəkətini hamarlaşdırmaq üçün istifadə olunur. Bu problemi həll etməyin iki yolu var: interpolyasiya və ekstrapolyasiya. İnterpolyasiya zamanı son iki vəziyyət götürülür və birindən digərinə keçid göstərilir. Onun dezavantajı ondan ibarətdir ki, müştəri həmişə keçmişdə baş verənləri görür, çünki az miqdarda gecikməyə səbəb olur. Ekstrapolyasiya, müştərinin qəbul etdiyi son vəziyyətə əsasən müəssisələrin indi harada olacağını proqnozlaşdırmaqdır. Onun dezavantajı ondan ibarətdir ki, əgər müəssisə hərəkət istiqamətini tamamilə dəyişərsə, o zaman proqnozla faktiki mövqe arasında böyük xəta olar.

Yalnız FPS-də faydalı olan ən son, ən qabaqcıl texnikadır gecikmə kompensasiyası. Gecikmə kompensasiyasından istifadə edərkən, server hədəfə atəş açarkən müştərinin gecikmələrini nəzərə alır. Məsələn, əgər bir oyunçu ekranında baş vuruşu həyata keçirdisə, amma əslində gecikmə səbəbindən hədəfi başqa yerdə idisə, gecikmə səbəbindən oyunçunu öldürmək hüququndan məhrum etmək ədalətsizlik olardı. Buna görə də, server oyunçunun ekranda gördüklərini simulyasiya etmək və atışları ilə hədəf arasında toqquşma olub olmadığını yoxlamaq üçün oyunçunun atəş açdığı ana qədər vaxtı geri çəkir.

Glenn Fiedler (həmişə olduğu kimi!) 2004-cü ildə bir məqalə yazdı Şəbəkə Fizikası (2004), burada o, server və müştəri arasında fizika simulyasiyalarının sinxronizasiyasının əsasını qoydu. 2014-cü ildə yeni silsilə məqalələr yazıb Şəbəkə fizikası, fizika simulyasiyalarını sinxronlaşdırmaq üçün digər üsulları təsvir edən.

Valve vikisində də iki məqalə var, Mənbə Multiplayer Şəbəkə и Müştəri/Server Oyundaxili Protokol Dizaynında və Optimallaşdırmada Gecikmənin Kompensasiyası Metodları gecikmələrə görə kompensasiya nəzərdə tutulur.

Aldatmanın qarşısının alınması

Aldatmanın qarşısını almaq üçün iki əsas üsul var.

Birincisi: fırıldaqçıların zərərli paketlər göndərməsini çətinləşdirir. Yuxarıda qeyd edildiyi kimi, bunu həyata keçirməyin yaxşı yolu şifrələmədir.

İkincisi: avtoritar server yalnız əmrlər/giriş/fəaliyyətlər qəbul etməlidir. Müştəri giriş göndərməkdən başqa serverdəki vəziyyəti dəyişdirə bilməməlidir. Bundan sonra, server hər dəfə daxilolma qəbul etdikdə ondan istifadə etməzdən əvvəl onun etibarlı olub olmadığını yoxlamalıdır.

Tətbiq məntiqi: nəticə

Yüksək gecikmələri və aşağı yeniləmə sürətlərini simulyasiya etmək üçün bir üsul tətbiq etməyi tövsiyə edirəm ki, hətta müştəri və server eyni kompüterdə işləyərkən belə, pis şəraitdə oyununuzun davranışını sınaya biləsiniz. Bu, gecikmə hamarlama texnikalarının həyata keçirilməsini xeyli asanlaşdıracaq.

Digər Faydalı Resurslar

Şəbəkə modelləri üzrə digər resursları araşdırmaq istəyirsinizsə, onları burada tapa bilərsiniz:

Mənbə: www.habr.com

Добавить комментарий