Yerel giriş tahmini nedeniyle oynatıcının durmasını nasıl engelleyebilirim?


14

Bir 2D sunucu-istemci çok oyunculu oyun motoru üzerinde çalışıyorum ( burada deneyebilirsiniz ). WebRTC DataChannels kullanır . (Bağlantılar eşler arasıdır, ancak ana bilgisayar eşi yine de bir sunucu görevi görür.)

En büyük sorun (bağlantı dışında) yerel girdi öngörüsüdür. Her zamanki gibi yaparız: Tuşa basıldığında, oyuncular anında hareket eder, ana bilgisayara hangi tuşlara basıldığını söyler, ana bilgisayardan veri alır ve tarihi konumla karşılaştırır. Bir fark varsa pozisyon zaman içinde düzeltilir. Ping yüksek olsa bile bu, düşük paket kaybı veya PDV ile iyi çalışır .

Kayıp veya PDV varsa, sapma daha büyük olabilir. Bunun nedeni, giriş değişikliğini gösteren ilk paketin ertelenmesi veya düşürülmesi durumunda, ana makinenin daha sonra öğrenmesi ve bu oynatıcıyı yerel giriş tahmininden daha sonra değiştirmeye başlamasıdır.

Oyuncu hareket ediyorsa, daha az farkedildiğinden, uygulanan düzeltme miktarını arttırdık. Bu, hareket etmeye başlarken ve hareket ederken boşlukları örtüyor gibi görünüyor. Bununla birlikte, ani bir duruşa gelirlerse herhangi bir düzeltme daha belirgindir. Daha sonra PDV veya kayıp, ana makinenin daha sonra durduklarını düşündüğü anlamına gelirse, ana bilgisayar aşır, biraz daha ileride olduklarını söyleyerek verileri geri gönderir ve düzeltme, oyuncuyu biraz sürükler. Kesintili bağlantılarda, oyuncular genellikle durduktan sonra fark edilir şekilde sürüklenirler.

Bunu diğer oyunlarda fark etmedim. Bu nasıl hafifletilebilir?


3
Sunucusu olan bir P2P oyunu mu? Burada yanlış bir şey var.
API-Beast

Hata! 'Sunucu' ile 'ana bilgisayar eşini' kastediyorum.
AshleysBrain

2
Bu, aynı zamanda eşler arası bir model gibi görünmüyor, çünkü sunuculardan biri sunucu olarak eşler arası görünmediğinden poz veriyor. Kullandığınız teknik kesinlikle bir İstemci-Sunucu tekniğidir. P2P'de ya tüm istemcilere tamamen güvenirsiniz (örneğin, her bir eş oyuncularına nerede olduklarını sorar) ya da hiçbirine güvenmezsiniz (örneğin, tüm eşler alınana kadar girişi geciktirirsiniz).
API-Beast

Ah ... bu gerçekten iyi bir nokta ... Karışık oldum: bağlantılar eşler arası (WebRTC'nin yaptığı şey), ancak motorun kendisi sunucu-istemci (eşlerden biri sadece sunucu ). İyi bir nokta.
AshleysBrain

2
Bu ne yapar beni düşün olduğunu bize ait Andrew Russell 'ın YouTube'da Çubuk Ninjalar dev günlükleri , özellikle öngörü hatalarını düzeltme konusundaki bu bir . Anlattığınız sürüklenme sesleri o videoda olanlara çok benziyor ve Andrew ayrıntıları anlatıyor. Bunlar ilişkili mi, belki de aynı sorun mu?
Anko

Yanıtlar:


8

Ağ katmanının üzerinde anlaşılmış bir saat olması gerekir. Onlar oyunun erken saatlerinde bir saat değeri üzerinde anlaşabilirler (ve sürüklenme durumunda periyodik olarak yeniden senkronize edebilirler), böylece ana bilgisayar belirli bir paketin gerçekte ne kadar sürdüğünü ve müşterinin eylemi ne zaman yaptığını bilir.

Oyunlarda saatleri senkronize etmenin olası bir yolu için bu makaleye bakın . Başkaları da var. Özel araçlar önemli değil.

Sorunun ikinci yarısı, sunucunun, istemcinin girdiyi uygulamayı durdurduğu zamana kadar girdi uygulamasıdır. Bu, sunucudaki geçmiş hareketlerin bir ara belleğini ve sunucudaki bilinen son hareketin ötesindeki hareket girişlerini yok saymak için istemcideki bazı mantık gerektirir.

İlk olarak, sunucu arabelleği. Sunucunun, oynatıcıdan alınan son girişin saat damgasını izlemesi gerekir. Ayrıca bir oyuncu için geçerli olan tüm hareketlere, hareketin saat damgasına ihtiyaç duyar. Bir giriş alınırsa , giriş paketinden daha yeni bir saat damgasıyla uygulanan tüm son hareketler bırakılır ve tüm hareketler giriş paketinden yeniden uygulanır. Bu nedenle, sunucu oynatıcıyı bazı girdilere göre fazla hareket ettirirse, güncellenen girdi bu hareketleri iptal eder ve oyuncunun yeni konumu sunucunun sahip olduğu en son girdi bilgisine dayanır.

İstemci tarafında, istemci sunucuya en son ne zaman girdi gönderdiğini bilir. Sunucudan gelen her oynatıcı güncellemesi, sunucunun bildiği son girişin saati ile etiketlenmiş olması gerektiğinden, istemci, süresi dolmuş bir giriş etiketine sahip sunucu güncellemelerini yoksayabilir ve sadece istemci tahminine sadık kalabilir. Sonunda yeni sunucu güncellemeleri güncel girdi ile gelir ve istemci bunlara karşı düzeltme yapabilir.

Sunucunun giriş saatlerini doğrulaması ve hile yapmayı önlemek için beklentilerden çok fazla kaymadığından emin olması gerekir. Giriş saati, hesaplamanız gereken yarım gidiş-dönüş süresinden büyük ölçüde daha büyük olmamalıdır. Makul bir aralıkta olanları kelepçeleyin ( [Now-2*RTT,Now]örneğin).

Gecikme yüksek olduğunda istemciler diğer oyuncuların avatarlarının çok fazla titremesini göreceklerdir, çünkü eski girdilere dayalı olarak sunucudan güncellemeler alacaklar, ancak eski olduğunu bilmenin bir yolu yoktur ve sunucu, dayalı olarak oldukça farklı konumlar göndermeye başlayabilir. aldığı güncellenmiş giriş (ve tarihinin bir kısmını bırakması ve yeni girişle tekrar oynatması). Diğer oyuncuların avatar titremenizi görmesi ile ilgili bu son sorun gerçekten düzeltilemez. Gecikme süreleri ve yüksek gecikmeli bağlantılara takılan oyuncular, kendi oyuncuları sorunsuz hareket etse bile diğer oyuncuların çok fazla titremesini göreceklerdir. Tek düzeltme daha iyi bağlantılarda veya daha az gecikmeli eşlerle / sunucularda oynamaktır.


1

Düğme durumu değişikliklerini ve konum düzeltmesi için güvenilir olmayan UDP mesajlarını belirtmek için güvenilir UDP mesajları kullandım. Temel olarak, aşağıdaki makaleler bana çok yardımcı oldu: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Yaklaşık 20 veya 30 devlet tasarrufu için gelen konum düzeltme mesajlarına göre oyuncu durumlarını sabit zaman aralıklarında depolayarak hareket tahmini hakkında diyor. Bu yüzden uzak oyuncuların sürekli tahmin tekniği uygulayarak şimdiye kadar değil bir "geçmiş" yaşayacak gibi görünüyor :) Net mesaj gecikme dayanarak nesnenin pozisyonu yaklaşık mesaj sadece ana bilgisayardan gönderildiği zaman alabilirsiniz.

Mevcut "ekran üstü" pozisyon daha sonra Lerp (doğrusal enterpolasyon) matematiği kullanılarak tahmin edilen pozisyona sorunsuzca çevrilebilir. Fikir, düzeltme paketleri arasındaki zaman boşluklarındaki değerleri enterpolasyona sokmaktır. Görünen nesnenin her zaman tahmin edilen bir konuma doğru hareket ettiği anlaşılıyor. İnterpolasyon değeri için 1'in "orta mesaj gecikmesine" ve "orta çerçeve oluşturma süresine" bölünerek hareketin düzgün görünmesini sağlarım.

Bu senaryoda oyun tüm istemcilerde hesaplanır ve sunucu zaman zaman hız ve pozisyon gibi değerleri düzeltir.

Bu durumda çok yardımcı olan bir şey daha var: oyun mantığınızı optimize edin, böylece sunucu ve istemcilerin oynatıcı girdisine dayalı benzer davranışlara yakın taklit edebilmelerini sağlayarak gecikme etkilerini kolayca ortadan kaldırabilirsiniz.

Projemde kullandığım tüm şemayı açıkladım, umarım sorunuzun cevabını bulacaksınız.

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.