Sunucuda oyun mantığı! İyi ya da kötü?


25

Şu anda basit bir çevrimiçi çok oyunculu oyun planlıyorum. Ve işte soru. Tüm oyun mantığını sunucuda yapmak ve girdiyi istemciden sunucuya göndermek mantıklı mı? Artıları ve eksileri nelerdir veya bunu yapmamam için herhangi bir neden var mı?

Yanıtlar:


37

Sunucuya oyuncu girişi göndermek istemiyorsunuz. Muhtemelen yapmak istediğin şey, oynatıcının sunucuya ne yapmak istediğine dair soyut bir sunum göndermek ve daha sonra da oradaki mantığı çalıştırmak.

Aynı şekilde, müşterinin yapması gereken her şeyi geri göndermek istemezsiniz. Örneğin, "NPC X öldü" diyen bir tür mesaj gönderebilirsiniz ve müşteri hangi animasyonun / seslerin çalınacağını belirler. Onun gibi şeyler.

İşin püf noktası, insanların aldatmalarını engelleyerek bant genişliğinin ve işlem gücünün (sunucudaki) azaldığı hattı bulmaktır. Genellikle, yalnızca sunucu üzerinde herhangi bir tür oyun değiştiren yetkili karar verirsiniz ve tüm yardımcı görsel şeyleri müşteriye bırakırsınız.

Bu konuda sitenin tamamında daha birçok soru var. Örneğin:

Çarpışma tespiti sunucu tarafında mı yoksa müşteri / sunucu arasında mı işbirliği yapmalı?

Bir MMO’da AI hesaplamalarını kim yapar?

Oyun sahibi otorite mi yoksa başka bir aptal müşteri mi olmalı?


4
+1 Beni yen. Ayrıca, oyunun tarzına bağlı olarak bazı müşteri tarafı tahminleri yapmak isteyebilirsiniz / gerekebilir.
John McDonald

14

Cevapların var ama gerçek cevabın "kendini dene". Şeyler oyundan oyuna değişir.

Dağıtılmış ağ oyun tasarımı kursu için birkaç multiplayer oyun yaptım. En zorlayıcı, birçok oyuncunun dahil olduğu ve cehennem gibi girdiler gönderdiği gerçek zamanlı bir aksiyon oyunu yapmaktı. Bu noktaya gelince, her şey sorun haline geliyor. Tetrat'ın gönderdiği ilk bağlantıyı gördüğünüz gibi, bir çarpışma belirleme bile bir sorun haline gelir. Gecikme, enterpolasyon, ekstrapolasyon, tahmin gibi terimleri okuyacaksınız.

Benim tavsiyem:

Adım 1
Sadece şimdilik tam yetkili sunucu tabanlı tasarımla başlayın. Dediğiniz gibi, sadece kullanıcı girişlerini sunucuya gönderin ve sunucunun her şeyi yapmasına izin verin; istemciler sonuçları alır. Oyununuz tamamen tutarlı çalışacak. Ancak müşterilerinize baktığınızda, bazı gecikmelerin, bazı ışınlanma problemlerinin, düzgün hareketlerin olmadığını fark edeceksiniz.

Adım 2
İstemci tarafındaki sorunları çözmeye başlayın. Örneğin ışınlanma problemleri. Karakterin (0,0) idi ve sunucu şu anda (100,100) olduğunu söyledi. Karakterin sadece (100,100) 'a ışınlanacak, bu hoş değil. İnterpolasyon var. Müşteri tarafında, karakteri (0,0) ile (100, 100) arasında yumuşak bir şekilde kayan bir kod olmalıdır. Evet, karakterinizi (0,0) 'dan (100,100)' e taşıyacaksınız ama ne kadar hızlı? Şimdilik sadece her sunucu güncellemesi arasındaki zaman farkını kullanabilirsiniz. Sunucunuz saniyede 10 paket gönderirse, bu her paket arasında 100 ms gecikme anlamına gelir.

Aşama 3
Artık oyununuz zaten (1-50) ms gecikmeli hızlı ağlar için iyi durumda. Ancak bir paket kaybı varsa, gecikme veya hesaplama sunucuda uzun sürerse mahkum olur ... vb. Sol oklara bastığınızda fark edeceğiniz bu durumlarda, karakterinizin 200 ms'lik bir gecikmeyle sola hareket ettiğini göreceksiniz. Paketiniz arasındaki gecikme sunucuya, hesaplama süresine gider ve son konumunuzla birlikte size geri döner. Bu kötü, sunucu yetkili tasarımın en kötü dezavantajı. Oyuncu, sola basar basmaz karakterini sola hareket ettirmek istiyor, onu bekletemezsin. Neyse ki müşteri aynı zamanda sunucu ile aynı koda sahip, peki neden hemen istemcide çalıştırmıyor ve nihai sonucu sunucudan gelen cevapla düzeltmiyorsunuz? Temelde girdi tahmini budur. Müşteri sola basarsa, tarafındaki kod onu sola doğru hareket ettirir, bir süre sonra 200 ms söylesin, asıl pozisyon sunucudan gelir ve müşteri onunla pozisyonunu düzeltir. Her şey yolunda giderse, müşteri hiçbir şey farketmez, "2. adım" da bu konuda bize yardımcı olacaktır.

Net'in bu konuda birçok öğretici ve bir çok şeyi var. Ama gerçekten sevdiğim 2 tane var:

Gerçekten iyi, siyah noktaları kapsar: Vana-Source Engine Multiplayer Ağ
Kind tarih, eğlence okumak için ve değer bunun: 28,8 1500 Okçular ,


3

Artıları:

  • bu yaklaşım daha (çoğu) korsan kanıtıdır
  • güncellemeleri daha kolay uygulayabilirsiniz
  • merkezi topluluk

Eksileri:

  • büyük bant genişliği gereksinimleri
  • bazı kullanıcılar bu yaklaşımdan nefret edebilir (gizlilik ve benzeri şeyler)
  • yerel oyun ile ilgili sorunlar (LAN partileri), singleplayer

LAN oynanışı ile ilgili problemler, tahsis edilmiş bir sunucu ikili sistemi sağlayarak veya istemcilerden birinin sunucu görevi görmesini sağlayarak önlenebilir. Hem tek oyunculu hem de LAN sorunlarını çözen bir çözüm, istemci bilgisayardaki bir sunucuyu şeffaf bir şekilde barındırmak olacaktır (eğer yalnızca tek oyunculu bir oyundursa, bu yaklaşım ile geleneksel bir ikili sistem arasındaki hesaplama gücünde önemli bir fark olmamalıdır). Bu, tüm oyun türleri için çalışmayabilir
3Doubloons

2

Sunucu tarafı mantığı aynı zamanda ölçeklenebilirlik problemleri yaratır - her müşterinin toplam işi kendi payını yapmasına izin veren ayetler - sunucunuzdaki tüm istemciler için tüm işi yapmanız gerekir.


2016'da burada benzer sorular sorduğumda komik, herkes bana "müşteriye asla güvenme" dedi.
newguy

Oyuna bağlı, ancak kendilerini aldatan müşteriler ciddi bir endişe değil, diğer dürüst müşterilere karşı hile yapan müşteriler; Sunucu müşteriye güvenmemek için ne yapmış olursa olsun, dürüst müşteriler bunun yerine yapabilir.
Ddyer

2

Hangi oyunu oluşturmak istediğinize ve oyunun hangi bölümüne bağlı olduğunuza bağlı. Eğer bir RTS (ya da kilitlenmiş bir modeli olan herhangi bir oyun) geliştiriyorsanız, o zaman kesinlikle sadece girişi ve hangi simülasyon adımının alındığı bilgisini göndermelisiniz.

Bir atıcı yapmak istiyorsanız, hem giriş hem de soyut işlevleri kullanabilirsiniz. Unreal Tournament 3'ü durum olarak alırsanız, çoklayıcıyı çoğunlukla çoğaltılmış işlev çağrıları aracılığıyla yarattılar.
Hareket için oynatıcı girdisini alır (her işlem için tek bir bit halinde sıkıştırılır) delta döndürme, hızlanma ve zaman damgası alır ve sunucuya gönderir.
Silah gibi diğer amaçlar için, ateş ederken senkronize olurlar (AFAIK, henüz bu bölüme derinlemesine bakmadım).
Daha statik / daha az sıklıkla değişen değerler için sağlık gibi, programcının belirttiğine bağlı olarak değişkeni istemciye veya sunucuya gönderir.

Ve RTS dışı oyunlar için müşteri öngörüsünü unutmayın.

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.