Gerçek zamanlı FPS oyununda sunucuya ne gönderilir?


23

Yerel oyuncumuzun sunucuya pozisyonunu söylemenin doğru yolu nedir? Bazı belgeler, girdileri üretildiği zaman göndermenin daha iyi olduğunu söylemektedir. Bazı belgeler müşterinin pozisyonunu sabit bir aralıkta gönderdiğini söylüyor.

Girişleri gönderme yaklaşımı ile: Oynatıcı yön tuşlarını basılı tutarsa ​​ne yapmalıyım? Bu, her çerçevede sunucuya bir paket göndermem gerektiği anlamına geliyor. Çok fazla değil mi? Ayrıca, oynatıcının fare girişinden dönmesi de var. İşte bir örnek:

http://www.gabrielgambetta.com/fpm_live.html

Pozisyonu sabit aralıklı yaklaşımla göndermeye ne dersin? Sunucuya çok az mesaj gönderir. Ancak aynı zamanda duyarlılığı azaltır.

Peki hangi yol daha iyi?

Yanıtlar:


19

Basit cevap: hile ya da bu kadar doğru olmayın!

Eğer çevrimiçi olarak biraz tetikçi oynadıysanız, sunucuya bağlantınız kötüyse büyük olasılıkla "lastik bantlama" denilen deneyime sahip olacaksınız.

Bunun nedeni müşterinizin zaman zaman pozisyonunuzu düzeltmesidir.

Temel olarak, iki tarafta neler olur:

  • Sunucu, hareketinizi izler ve beklendiği gibi istemcilere güncelleştirmeler gönderir. Bunlar her zaman tam güncellemeler olmak zorunda değildir. Her x karesi tam bir güncelleme olabilir, diğer tüm kareler sadece yeni hız vektörleri gönderir (eğer herhangi bir değişiklik varsa).

  • Kendi müşteriniz serbestçe hareket etmenize izin verecek, ancak konumunuzu düzeltmek / ayarlamak için sunucu tarafından sağlanan güncellemeleri kullanacaktır. Bu, pozisyon çerçevesini güncellemeseniz bile, oyunun duyarlı hissetmesini sağlayacaktır.

Fakat girdi nasıl işlenir? Müşteriniz konumunuzu "Oraya taşındım" sunucusuna gönderir. Sunucu bu güncellemeyi doğrulayacaktır (örneğin, o kadar hızlı hareket edebilmeniz gerekir mi?) Ve eğer geçerliyse sizi hareket ettirir (veya güncellemenizi reddederek "lastik bantlama" ile sonuçlanır).

Yani evet, sabit aralıklı yaklaşımınız büyük olasılıkla işe yarayacak ve yeterli olacaktır.

Ancak, giriş göndermek ve her iki taraftaki hareketi idare etmek isteseniz bile, "düğmeye hala basıldığını" göndermek zorunda olmadığınızı unutmayın. Bunun yerine, düğmeye basıldığında bir olay ve düğmeye bırakıldığında bir tane daha gönderin.


5
Evet butonu basıp bırakabileceğimi takip edebiliyorum. Peki ya fare girişi? Sürekli değişiyor.
syloc

6
"Bunun yerine, düğmeye basıldığında bir olay ve düğmeye basıldığında bir başkası gönderin." - Doğru, ancak oyunların kurallarına bağlı olarak, "yayınlanma" olayının sonunda zorunlu kıldığından emin olmak için kontroller yapılması gerekir. Örneğin, Rainbow Six Vegas 2 çok oyunculu oyununda bir oyuncu silahını ateşlemeye başlayabilir ve (ne yazık ki yaygın) bir hata "ateş etmeyi durdur" mesajının başarıyla sunucuya ulaşmamasına neden olur. Bu, maçın geri kalanında sonsuz bir döngüde kalan silah sesiyle sonuçlanır. Dikkatli olmak için sadece bir örnek. youtu.be/GOQIbLCy7m8?t=9m10s
Mike Baxter

@syloc: Sadece istemci tarafını kullanın ve sunucunun hareketin geçerli / mümkün olup olmadığını belirlemesine izin verin (ışınlanma kesmeleri ve benzeri şeyleri önlemek için).
Mario

@syloc Yalnızca fare için bir aralık belirleyin, ancak fazladan bant genişliği kaydetmek için hala değişip değişmediğini görmek için müşteri tarafı denetimi yapın. Fare hareketi olmayan bir süre varsa, mesaj göndermeye devam etmene gerek yok.
agweber

İşlerimden birinde, çevirmenlik için (13 yıl önce) cevapsız pozisyon güncellemeleri için bahar davranışını optimize etmek için pratik olarak kendini çıldırttı. Şimdi çok fazla bant genişliği olan ve gülünç derecede düşük gecikmeli bu sorundan muzdarip oyunlar görüyorum, bu sorun daha önce hiç bitmeyecek veya insanların bu günlerde çok daha az umursadığı görünüyor.
Andon M. Coleman

5

Henüz yapmadıysanız, bu iki derin ancak anlaşılır makaleyi okumanızı öneririm: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking ve http://fabiensanglard.net/quake3/network.php .

Bunlar, neden 'sabit aralıklı' paket gönderimi kullanmanın önerildiğini açıklamaktadır. Kısacası, aslında sunucu tarafından gönderilen paketler için önemlidir.

Bir paket göndermenin sabit bir maliyeti vardır ve bir ağ paketinin maksimum boyutu yaklaşık 1,5 KB'dir. Eğer sunucunuzda örneğin 16 oyuncu varsa, bir oyuncu için hareketi hesapladığınızda her kare, naif kod her hareket çözünürlüğünden sonra her oyuncuya bir güncelleme paketi gönderebilir, yani 16 * 16 = 256 paket. 30'luk bir kare hızınız varsa, bu 7680 pakettir.

Daha iyi bir yaklaşım, çerçevenin her başlangıcında bir tampon oluşturmak, içinde hesaplanmış 16 konum güncellemenizi birleştirmek ve sonra bunları 16 oynatıcınıza göndermek.

Şimdi aynı sonuçları elde etmek için saniyede yalnızca 480 paket gönderiyorsunuz.

Oyuncudan sunucuya durumda, bu aynı pakette, örneğin; pozisyon baktı, eylemler bu çerçeveye çağırdı ve böyle devam etti.

Sorunuzun ikinci kısmı hakkında - gecikme hissini azaltmayı tercih etme yöntemim, bu bilgiyi her karedeki sunucuya göndermek oldu:

  • oyuncunun gerçek geçerli konumu (sunucu tarafı ve oyuncu tarafı konumlarının fazla senkronize edilip edilmediğini kontrol etmek için sunucu tarafından kullanılır).

  • 1 saniyede tahmini oyuncu pozisyonu: müşteri tarafından hesaplanır: oyuncu fare yönünü değiştirmezse ve klavyeyi geçerli durumda 1 saniye bırakırsa oyuncu nerede olur? (Çarpışmaları umursamıyoruz) Eğer oyuncu hareket etmiyorsa, 1 saniye içinde tahmin edilen pozisyonu mevcut pozisyonudur.

  • Baktığı pozisyon.

Sunucu bu bilgiyi her aldığında, gelecekteki pozisyonu ve bakılan pozisyonu günceller ve oyuncu varlığı eninde sonunda pozisyonuna geçer.

Oyuncular hiçbir zaman tam olarak senkronize edilmez, ancak giriş yanıtı anındadır (benim için en önemli olan) ve tahmin edilen konumların benim için yeterince doğru olduğunu tespit ettim.


"Oyuncular asla asla tam olarak senkronize edilmez" Bence buradaki doğruluk seviyesinin gerçek oyuna (oyuna) bağlı olduğunu belirtmek önemlidir. Örneğin, varlıkları tıklayıp seçtiğiniz klasik bir MMO, hemen hemen her şey için mükemmel bir kesinliğe ihtiyaç duymaz, ancak mükemmel senkronizasyonu iyi olan bir tetikçide esastır.
Mario

Durum şu ki, aklı başında hiç kimse bir FPS için TCP kullanmıyor. TCP ek yüküne uğramak yerine karmaşık yeniden sıralama ve cevapsız datagramlarla uğraşmayı tercih ederler.
Andon M. Coleman
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.