Ş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ı?
Ş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:
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ı?
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 ,
Artıları:
Eksileri:
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.
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.