Bir ağ oyunu nasıl yazılır? [kapalı]


73

Dayanarak Niçin bir MMO geliştirmek için bu kadar zor? :

Ağa bağlı oyun geliştirme önemsiz değildir; sadece gecikmede değil, hile engellemede, devlet yönetiminde ve yük dengelemede üstesinden gelinmesi gereken büyük engeller var. Ağa bağlı bir oyun yazma konusunda deneyimli değilseniz, bu zor bir öğrenme alıştırması olacaktır.

Soketler, sunucular, müşteriler, protokoller, bağlantılar ve benzeri konularla ilgili teoriyi biliyorum.

Şimdi nasıl bir ağ oyunu yazmayı öğrenebileceğini merak ediyorum:

  • Yük sorunları nasıl dengelenir?
  • Oyun durumu nasıl yönetilir?
  • Eşitleme nasıl yapılır?
  • İletişimi ve müşteriyi tersine mühendislikten nasıl koruyabilirim?
  • Gecikme problemleri etrafında nasıl çalışılır?
  • Hangi şeyler yerel olarak hesaplanmalı ve sunucuda hangi şeyler bulunmalıdır?
  • ...

Bu konuda iyi kitaplar, öğreticiler, siteler, ilginç makaleler veya başka sorular var mı?

Geniş cevaplar arıyorum, ancak aradaki farkı aradaki farkı öğrenmek için iyi.


4
Evet, kitaplar, öğreticiler, siteler, ilginç makaleler ve bununla ilgili diğer sorular var.
Ricket

2
Soruyu değiştirmeden sormaya zorlamak ve bu soruyu cevapları hak ettiği için kullanıcılara cevap vermeleri için bir neden verdim, bu nedenle en iyi cevaplayıcı işlerinde itibar kazanıyor ancak soruyu cevaplayan tek bir cevap yok.
Tamara Wijsman

Yanıtlar:


61

Diğer cevaplarda yer alan makaleye ek olarak, Arianne Projesi'nin deneyiminden biraz bahsedebilirim .

Eşitleme nasıl yapılır?

Eylem ve algı kavramı etrafında bir “„ Marauroa “ çerçevesi oluşturduk: Müşterilerden kullanıcı girişi yapan sunucuya gönderilir (sola doğru yürü, canavarlara saldır # 47, 'merhaba'). Ve algılayıcılar sunucudan istemcilere, etraflarındaki dünyanın durumunu anlatan müşterilere gönderilir. Bu algılamalar her dönüşe gönderilir. Oyuna bağlı olarak 30ms'den 300ms'ye kadar dönüş süreleri kullanıyoruz.

İki tür algılamaya sahibiz : Giriş sırasında ve oyuncu yeni bir alana (bölge) girdiğinde tam bir algı gönderilir. Bundan sonra, sadece değiştirilmiş nesnelerin değiştirilmiş özniteliklerini (örneğin konumu) ve elbette yeni ve kaldırılmış nesneleri içeren farklı algılar gönderilir.

Gecikme problemleri etrafında nasıl çalışılır?

“Sunucu her zaman haklıdır” inancına büyük önem veriyoruz. Müşteri düzgün yürüme, çarpışma kontrolleri vb. Gibi bazı öngörülerde bulunur. Ancak bir müşteri ve sunucu bir konuda anlaşamazlarsa, sunucu kazanır. Alt proje Stendhal (2B RPG), varsayılan olarak 300ms'lik bir dönüş süresi kullanır (çok fazla düzeltme işlemi yapılmış istemci tarafında). Bu Stendhal'ı gecikmeye karşı çok dirençli kılar.

Not: Diğer bazı oyunlar, ağ gecikmesinin etkisini en aza indirgemek için müşterinin bir kısmına kadar uzanmasına güvenir. WoW'da genellikle “Warsong Gulch” adlı savaş alanlarından birinde istismar edildi. Bayraklı bir oyuncunun seçebileceği iki yol vardır: Ortada bir tünelden geçerken ve diğeri de tepeden yukarı çıkarken. Bu yüzden hile yapan bir oyuncu tünele doğru koşar ve sonra kendisi için gecikmeye neden olur. Sunucu ve diğer müşteriler ona doğru çalıştığını görmeye devam edecek. Ancak, bir süre sonra bu müşteri sunucuya tepeye doğru gittiğini söyleyebilir. WoW, iletilen son koordinatlar ile mevcut olanlar arasındaki mesafenin zaman dilimine uyduğunu kontrol eder ve bunu kabul eder.

TCP ve UDP Kullanımı

İlk sürümlerde, TCP ek yükünü azaltmak için UDP kullandık. Kayıp paketleri kendi başımıza ele aldık. Bu projenin ilk günlerinde mükemmel çalıştı. Ancak sunucu birkaç yıl önce bazı ev DSL bağlantılarından gerçek bir veri merkezine taşındığında, çok büyük sorunlarımız oldu. UDP, (veya en az 5 yıl önce), güvenlik duvarı donanımının CPU gücünden aşırı derecede talep görüyor: Kural, her bir UDP paketine uygulanmalıdır. Ancak, TCP için kural sadece ilk 3 paket için uygulanır. Bundan sonra bağlantı kurulur. Aşağıdaki tüm paketler, bağlantı izleme tablosunda oldukları veya SYN bayrağı bulunmadıkları için normal kural kümesini atlayacaktır.

İletişimi ve müşteriyi tersine mühendislikten nasıl koruyabilirim?

Arianne tamamen açık bir kaynaktır, buna müşteri, sunucu, grafik, müzik de dahildir. Ve tabii ki protokol dokümantasyonumuzu ve hatta hata ayıklama için kullanılan bir analizörü de içeriyor .

İletişimi, üçüncü taraflarca SSL kullanarak yetkisiz koklamalara karşı korumak kolaydır.

Bununla birlikte, tersine mühendislikten korumak mümkün değildir. Bunu karıştırdığınızdan ve hata ayıklama önleme teknikleri kullandığınızdan emin olun. Ancak sonunda, kullanıcılara verdiğiniz yazılımın tersine mühendislik edilmesini önleyemezsiniz. Geliştiricilerin hata ayıklama tekniklerine çok çaba sarf etmesine rağmen, Skype'ın nasıl tersine çevrildiğine dair ilginç bir sunum var: http://recon.cx/en/f/vskype-part1.pdf

Not: Tersine mühendisliğin yasa dışı olduğu veya lisansa veya Paragraf'a tersine mühendislikten izin vermeyen bir paragraf koymasına izin veren bazı ülkeler vardır. Ancak, uyumlu veri depolama formatları veya aktarım protokolleri, lisanstaki paragraflar veya geçersiz olanlara izin vermeye çalışan ToS paragrafları veya bağlamında geliştirme bağlamında açıkça tersine mühendislik sağlayan diğer ülkeler (içinde yaşadığım gibi) vardır. (Bu bölümdeki her şey bildiğim kadarıyla ben avukat değilim)

Hangi şeyler yerel olarak hesaplanmalı ve sunucuda hangi şeyler bulunmalıdır?

Sunucudaki oyun mantığı ile ilgili her şeyi hesaplıyoruz. Müşteri, oyunun sorunsuz bir şekilde oynanabilmesi için bazı olayları önceden tahmin edecektir. Ancak sonunda sunucu her zaman haklıdır.

Öngörülen olaylar, örneğin bir çarpışma gerçekleştiğinde hareketi durdurmak içindir. Stendhal, elemanları konumlandırmak için bir ızgara kullanır. Ve sunucu bakış açısından, her varlığın sol üst köşesi tam olarak bir karedir. Ancak müşteri bunları döşemeler arasında rahatça hareket ettirir. Ayrıca sözde 3d efekti çizecek. Dolayısıyla, müşteride 1x1 tabanı olan bir varlık daha yüksek olabilir.

Yük sorunları nasıl dengelenir?

Bakımı kolaylaştırmak için bunu olabildiğince basit tutmaya çalışın.

Statik içeriğin yük dengelemesi, http sunucu kümeleri ve içerik dağıtım ağları alanında iyi bilinmektedir.

Oyun hizmetlerinin yük dengelemesi için oldukça basit bir kavram, sunucuları bölgelere / bölgelere bölmektir. Öyleyse AC bölgesi bir sunucuda ve DF bölgesi başka bir yerdedir. Bu, özellikle bir kümedeki bölgelerden başka bir kümedeki bölgelere bakamıyorsanız kolaydır. Bir müşterinin yalnızca oynatıcının bulunduğu bölgeden sorumlu bir bölge sunucusuna bağlanabilmesi için bazı denetimler koymanız gerekir.

Oyuncuları bir sunucudan diğerine transfer etmenin en kolay yolu, onları veritabanına yazmak, müşteriye diğer bölge sunucusuna bağlanmasını ve geçerli olandan bağlantısını kesmektir. İstemci daha sonra veritabanından yükleyeceği yeni bölge sunucusuna bağlanacaktır. (Zaten / store'dan veritabanı koduna kadar yüke ihtiyacınız olduğundan, aktarma sunucuları arasında doğrudan iletişim daha sonra gerçekleştirilebilir).

Bazı ek küresel hizmetlere aşağıdakiler aracılığıyla ihtiyaç duyulur: Oturum açıldığında istemcilere doğru bölge sunucusuna bağlanmaları söylenmelidir. Ve dünya çapında bir sohbet sistemi isteyebilirsiniz.

Bu konuda MMO'larda yük dengelemesi nasıl sağlanır?


1
UDP'nin biraz daha fazla CPU gerektirdiğini söylemiştiniz, ancak paketin işlenmesinden önce TCP'nin istemci ile sunucu arasında en az üç kez gezinme gerektirdiğinden bahsetmediniz, ve paketler önceki tüm paketler alınana kadar arabelleğe alınır; Artık alakalı olmayan paketleri bekleyen gecikme süreleri. Bahsetmek için önemli bir şey gibi görünüyor.
BlueRaja - Danny Pflughoeft 24:11

2
@ Danny, Yeni bir TCP bağlantısı başlatmak için gerekli üç paket vardır: istemciden sunucuya: SYN, sunucudan istemciye: SYN ACK, istemciden sunucuya: ACK + data. Bu, UDP'den daha fazla gidiş-dönüş bir yolculuktur, ancak yalnızca müşterinin sunucuya ilk kez başvurması ile başlar. Yerleşik bir bağlantıda, her paket herhangi bir ek tur atmadan hemen işlenir. Bir ACK-cevabı verilecek ancak ACK paketleri geri giderken alınan verilerin zaten işlendiği görülecektir.
Hendrik Brummermann

1
@Danny, TCP paket kaybını otomatik ve oldukça verimli bir şekilde ele alır. UDP kullanarak kendiniz yeniden uygulamak zordur; protokolünüz rastgele teslim edilmemiş paketlerle uygun değilse. Bir sonraki sorun, TCP'nin paketlerin sırasını almasını sağlarken, UDP paketleri yanlış sırada alınabilir. Yine, örneğin bir paket sayacını temel alan eski paketleri görmezden gelmediğiniz sürece, kendinize yeniden uygulamak zordur. TCP için çok kısa bir yanıt süresi gerekiyorsa, Nagle algoritmasının devre dışı bırakılması gerekir.
Hendrik Brummermann

Çok gerçek TCP gecikme sorununu ele almadan pozisyonunuzu şiddetle savunduğunuz anlaşılıyor. Belki de asıl sorun,
DDoS'a

27

http://gafferongames.com/networking-for-game-programmers/

Oyun ağları ile ilgili çeşitli problemler ve çözümlerle ilgili harika bir makale kümesidir.


1
+1, ama lütfen onlara kör olarak güvenme. Tecrübelerime göre örneğin UDP kullanmak ve TCP özelliğini yeniden icat etmek iyi bir fikir değil. UPD sadece kayıp paketlerin hiç bir etkisi olmadığında faydalıdır, yani her UDP paketi dünyanın bütünüyle ilgili durumunu içerir. WoW TCP kullanır, SL UDP'den TCP'ye (devam eden statik içerik için bile HTTP) geçiş sürecindedir ve bu değişikliklerle performansı önemli ölçüde artırmıştır.
Hendrik Brummermann

7
En azından hepsi değil, TCP özelliklerini yeniden icat edemezsiniz. TCP akış kontrolü ve paket kaybı semantiği, düşük gecikmeli bağlantı gerektiren bir oyun için korkunç. TCP, gecikmeyi umursamıyorsanız veya gerekli bant genişliğini en aza indirirseniz faydalıdır.
jsimmons

2
Second Life, TCP üzerinden UDP'den HTTP'ye geçerek
Hendrik Brummermann

5
Gerçekten de, çalışma şeklini değiştirerek varlık akışlarının performansını artırdılar. Bu durumda HTTP / TCP kullanmak, daha hızlı değil, uygulamalarını kolaylaştırdı. Zeromq'un ilginç bir proje olduğunu ve oyun ağlarına çok iyi ölçeklenebileceğini de not edebilirim. zeromq.org
jsimmons

8

Yazdığınız oyun türüne bağlı olarak, bazı düşük seviyeli ağ programlamasından kaçınmanız mümkün olabilir. Bazı oyun türleri, istemciler ve sunucu arasında çok fazla ileri ve geri iletişim gerektirmez. Bu gibi durumlarda, daha yüksek düzeyde bir çerçeve kullanılması tercih edilebilir. Örneğin, C # /. NET'te sıra tabanlı bir strateji oyunu geliştiriyorum. Sıra tabanlı strateji oyunları, müşteri / sunucu iletişiminin büyük çoğunluğunun bir dönüşün başında ve sonunda gerçekleştiği, aralarında göreceli olarak az miktarda olduğu için benzersizdir. Bu nedenle, öncelikle web hizmetleri için tasarlanmış üst düzey bir iletişim çerçevesi olan Windows Communication Foundation'ı (WCF) kullanmayı seçtim. Doğrudan soketlerle ve bu düşük seviyeli ağ bağlantısının tümü ile çalışmak yerine, standart yöntem çağrıları olarak görünenleri yapabilirim. ve WCF'nin benim için protokol ve taşıma katmanları ile ilgilenmesine izin verin. Düşük seviyeli ağ işleriyle uğraşmak zorunda olduğum tek zaman, bitiş noktalarımı yapılandırdığım zamandı, bu bir yapılandırma dosyasında hemen hemen tek seferlik bir anlaşma. Bazı özel seri hale getirme mantığını uygulamak için hala gerekli olabilir, ancak ne olursa olsun böyle bir şey yapmanız gerekebilir.


8

Soru çok geniş. Cevaplar bir web sitesini kendi başlarına doldurabilir. Ancak, buna değinen kitaplar var, öncelikle bu ikisi:

Bu kitapların bile eksiksiz bir rehber olmadığını, bunun yerine, bazıları birlikte çalışmayacak, hatta çelişkili olabilecek, kullanabileceğiniz fikir ve yaklaşımların bir derlemesi olduğunu unutmayın. Genellikle bazı oyunlar, ağ uygulamaları veya ideal olarak her ikisini de geliştirme deneyimi olduğunu varsayar.

(Orijinal sorudaki MMO'lardan daha fazla bahsettiğime dikkat edin - bir 'ağ oyunu' PHP tabanlı bir metin oyunundan bir MMO'ya kadar her türlü anlama gelebilir ve yukarıdaki alt sorular da hepsi değildir. her tip için geçerlidir.)


7

Yük sorunları nasıl dengelenir?

sabit coğrafi boyut + çoklu durumlar en kolay çözümdür. SWG'de çalışan adamlar dinamik boyutu denedi ve pişman oldu.

Oyun durumu nasıl yönetilir?

Sunucu yetkilidir.

Eşitleme nasıl yapılır?

Sunucudan periyodik senkronizasyon güncellemeleri. (endişe burada ne olduğundan emin değilim)

İletişimi ve müşteriyi tersine mühendislikten nasıl koruyabilirim?

İmkansız. Müşteriden aldığınız hiçbir şeye güvenmediğinizden ve sunucunun yetkili olduğundan emin olun.

Gecikme problemleri etrafında nasıl çalışılır?

Bu işlem milin derinliklerine uzanıyor, ancak yüzeysel olarak istemcide sunucu ile aynı simülasyonu kullanıyorsunuz ve senkronizasyon gerçekleştiğinde işleri düzeltiyorsunuz. İstemcide alınan tüm kararlar sunucuda da simüle edilir, bu nedenle kötü kararlar olabilir, ancak genellikle işler yolunda gider.

Hangi şeyler yerel olarak hesaplanmalı ve sunucuda hangi şeyler bulunmalıdır?

İstemciyi, sunucuda neler olup bittiğinin yetkili olmayan bir simülasyonunu çalıştığını düşünün. Duyarlılık oyuncu deneyimi için anahtardır, bu yüzden oyuncu bir bara yeni başlasa bile her karar verdiğinde bir şey yapmalısınız .

Gerçeği söylemek gerekirse, bu sorunların çoğu diktir ve daha sonra uygulanan çözümler olabilir. Sadece oyunu yapmaya başla ve bu şeyler hakkında fazla endişelenme.


4

Bu soru çok geniş. Aynı zamanda ustalaşmak için çok zor bir alandır, ağ programcıları endüstrideki eşleşen bir ücretle oldukça aranır, bu da 'çözülmemiş' bir alan olduğunu gösterir. Dışarıda kitaplar var mı, evet, bolca. Şüphesiz orada güzel kitaplar var mı? Sorularınıza cevap verecek kitaplar var mı? Sanmıyorum. Bazı durumlarda işe yarayacak çözümlere sahip olabilir ya da ne arayacaklarına dair işaretçiler olabilir, ancak neredeyse tüm sorularınız oyun bağımlıdır .... bu gerçekten çok fazla çalışmanız gereken bir alan, görünüşte öyle görünüyor ki önemsiz ve birçok (kontrolsüz) şekilde yanlış gidebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.