Sunucu Tarafı Girişi


9

Şu anda oyunumda, müşteri bir renderer'dan başka bir şey değil. Giriş durumu değiştiğinde, istemci sunucuya bir paket gönderir ve oynatıcıyı girişi işliyormuş gibi hareket ettirir, ancak sunucu pozisyonda son sözü söyler.

Bu, büyük bir sorun dışında genellikle gerçekten iyi çalışır: kenarlardan düşmek. Temel olarak, bir oyuncu bir kenara doğru yürüyorsa, bir uçurum söyleyin ve kenardan çıkmadan hemen önce durursa, bazen bir saniye sonra, kenardan ışınlanır. Bunun nedeni, sunucu bilgileri işledikten sonra "W tuşuna basmayı bıraktım" paketinin gönderilmesidir.

Ne demek istediğimi anlamanıza yardımcı olacak bir gecikme şeması: http://i.imgur.com/Prr8K.png

Sunucunun işlemesi için her kareye bir "W Pressed" paketi gönderebilirim, ancak bu bant genişliği maliyetli bir çözüm gibi görünüyor.

Herhangi bir yardım takdir!

Yanıtlar:


5

Sunucu pozisyonda son söze sahip olsa da, bunu giriş ve konum olarak müşterinin ne gönderdiğini doğrulayarak ve akıl sağlığını kontrol ederek yapmalıdır. Bunu söylüyorum çünkü yaptığınız şey oyuncuyu hemen hareket ettirmek ve kodunuzda yaratılan beklenti, müşterinin gerçek pozisyon olması.

Genel olarak iyi çalıştığını düşünüyorsunuz, ama değil. Yan not: istemcinizin bir oluşturucudan başka bir şey olmadığını söylüyorsunuz, daha sonra sunucu iletileri olmadan hareket etmek için derhal yerel kontrol verin. Her iki yöne de sahip olamazsınız, ya sunucunun size hareket etmenizi söylemesini bekleyin ya da konumunuz üzerinde biraz kontrol sahibi olun ve hileleri doğrulamak için sunucuyu kullanın.

Yanıtlarınızın bir saniyeye ulaştığını not ediyorum. Bu, her türlü aksiyon oyunu için gülünç derecede büyük olan 500ms gecikme süresidir. Bu geri dönüşün neden bu kadar uzun sürdüğünü bulmaya çalışın, komut kuyruklarından derhal ele alınmamaktan su basmış bant genişliğine ve hatta birçok paket kaybına neden olan şeytanlara kadar her şey olabilir.

Olması gerektiğini düşündüğüm şey

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

Buradaki zor kısım, bir istemci kendisi hakkında bir mesaj alırsa, bu mesaj "geçersiz taşıma, bunun yerine XYZ'ye git" gibi bir şey olmadığı sürece çoğunlukla görmezden gelmesi gerektiğidir. Bu mesaj, başkalarının müşterileri için bilgi alıyorsanız, zaman içinde ileriye doğru tahmin etmek zorunda kalacaksınız, böylece nerede olacağına benziyor.


Müşteri pozisyonunu hiç göndermez; sadece tahmin eder / enterpolatlar. Bu yüzden kenarda olduğunu düşündüğünde kenarlardan düşüyor. Ayrıca, gecikmenin 1 saniye olduğunu söylediğim yeri görmüyorum, daha çok 8ms (yerel test) ila 100ms (internet üzerinden) gibi. Oyuncunun daha sonra tekrar ayarlandığını söyledim çünkü periyodik olarak tam pozisyon güncellemeleri gönderdim. İstemcinin basıldığı tuşlarla birlikte olması gerektiğini düşündüğü konumu göndermem gerektiğini ve sunucunun mümkün olduğunu doğrulaması gerektiğini anlamış mıyım?
Thomas

“bazen bir saniye sonra ışınlanacak” ima büyük zaman gecikmeleri. Duyarlı bir aksiyon oyunu için evet, istemci oynar ve sunucu zamanında oynar ve istemcinin yasa dışı bir şey yapıp yapmadığını bildirir. Çevrimiçi çok oyunculu oyunlarda, çoğunlukla diğer kişilerin pozisyon değiştirdiğini (sunucudan gelenler) gördüğünüzde , kendi pozisyonunuz doğrudan sunucu düzeltmelerinden çok nadiren değişir. Diğer insanlar görmek size ... vb pozisyonu, vardiya
Patrick Hughes

Bu yine de oynatıcının sunucudaki kenarından düşmesine neden olamaz mı? Her kareyi bir paket göndermezsek, sunucu yine de oynatıcının yaklaşık 32 ms hareket ettiğini düşünebilir. (Sadece her üç karede bir paket gönderiyorum). Yoksa sunucudaki girişi simüle etmememi mi, sadece konumun basılan girdinin sınırları içinde olup olmadığını kontrol etmeyi mi öneriyorsunuz?
Thomas

Sunucu yalnızca istemci tarafından bildirilen geçersiz hareketi düzelttiği için, istemcinin kendisi kenarın hemen üstüne gitmedikçe asla "uçurumdan düştünüz" göndermez. Bu geri bildirim döngüsünde, kendisini istemcinin dünyaya ve onun içindeki konumuna göre düzelten sunucudur. Hareket, oyuncuya canlı ve duyarlı davranacaktır. Dünya nesneleriyle etkileşim kurmak gibi diğer eylemler, sunucunun müşteriye ne olduğunu anlatmasını beklemeyi, bir kutuyu tıklamayı ve yanıt beklemeyi içerir, ancak burada sadece hareketten bahsediyoruz.
Patrick Hughes

Şu anda yaptığım şeye çok benziyor; sunucuya bir konum göndermek ve sunucunun oynatıcının bu konuma taşınıp taşınmayacağını doğrulamasını sağlamak. Bu daha sezgisel bir yaklaşım gibi görünüyor ve bence sunucunun karar vermesi kadar etkili olmayacaktı. Her paketle birlikte zaman damgası göndermek işe yarar mı? Bunun sorunu ortadan kaldıracağını düşünüyorum. Halo ve Source motorunu kullanan oyunların bunu kullandığına inanıyorum.
Thomas

0

Sorunuzu şu şekilde anlıyorum:

'İleri' düğmesine basmaya başladığımda sunucu bir paket ve son olarak 'ileri' düğmesini bıraktığımda başka bir paket alıyor. Bu nedenle, sunucudaki gerçek hareket, gerçek oyunda yaklaşık 100 milisaniye 'çok geç' ile başlar ve oyuncunun istemci tarafında ifade ettiği şeye kıyasla. Dolayısıyla, oyuncu 10 saniye hareket etmek istiyorsa, x >= 1çevrimiçi yerine 10.x saniye hareket edebilir .

Bu kötü bir tasarım stratejisidir, çünkü oyuncu istediği gibi oyuncunun oyun dünyasındaki iradesini ifade etmez ve oldukça zayıf bir kullanıcı deneyimi yaratır.

Önereceğim çözüm, oyuncunun kaç adım attığını ve hangi yönde olduğunu gösteren bir paket (olabildiğince sık) göndermektir. Daha sonra sunucu, doğruluk kontrolünden geçerse oyun dünyasını yeni oyuncu konumuyla günceller. Böylece oyuncu büyük bir hassasiyetle hareket edebilir ve yüksek çıkıntılardan düşmeyi önleyebilir.

Alternatif, oyuncunun son saniyedeki pozisyonlarını hatırlamak ve geriye dönük olarak pozisyonu düğmenin bırakıldığı zamana düzeltmek olacaktır. Eski günlerin lastik bant etkisini yaratacak gibi görünüyor. (Sadece farklı bir nedenden dolayı)

Temel olarak, hangi düğmeye basıldığını ve düğmeye basıldığı gerçek oyun zamanının ne olduğunu ve daha sonra hangi düğmenin serbest bırakıldığını ve tam olarak ne zaman yayınlandığını paketlemeniz gerekir.


Patrick'e söylediğim gibi, çözümün daha çok sezgisel bir yaklaşım olacağını düşünüyorum; sunucu "Adam" olmak yerine, sunucu bunun yerine istemci verilerini geçerliliğini kontrol eder. Bu, elbette, gecikme veya diğer ağ sorunlarının yanlış pozitifler oluşturmaması için biraz boşluk yaratması gerekecektir.
Thomas
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.