Megapack: Factorio 200 Oyunculu Çok Oyunculu Sorunu Nasıl Çözdü?

Megapack: Factorio 200 Oyunculu Çok Oyunculu Sorunu Nasıl Çözdü?
Bu yılın mayıs ayında oyuncu olarak katıldım. MMO etkinlikleri KatherineOfSky. Oyuncu sayısı belirli bir sayıya ulaştığında birkaç dakikada bir bazılarının “düştüğünü” fark ettim. Şans eseri senin için (ama benim için değil), ben de bağlantıyı kesen oyunculardan biriydim her zamaniyi bir bağlantı olsa bile. Bunu kişisel bir meydan okuma olarak algıladım ve sorunun nedenlerini aramaya başladım. Üç hafta süren hata ayıklama, test etme ve düzeltmelerden sonra hata nihayet düzeltildi ancak yolculuk o kadar da kolay olmadı.

Çok oyunculu oyunlarla ilgili sorunların izini sürmek çok zordur. Genellikle çok spesifik ağ parametreleri ve çok spesifik oyun koşulları altında (bu durumda 200'den fazla oyuncuyla) meydana gelirler. Sorun yeniden oluşturulabildiğinde bile, kesme noktalarının eklenmesi oyunu durdurduğu, zamanlayıcıları karıştırdığı ve genellikle bağlantının zaman aşımına uğramasına neden olduğu için düzgün bir şekilde hata ayıklanamaz. Ancak ısrar ve harika bir araç sayesinde sakar Neler olduğunu öğrenmeyi başardım.

Kısacası, gecikme durumu simülasyonundaki bir hata ve eksik uygulama nedeniyle, istemci bazen kendisini bir saat döngüsünde yaklaşık 400 oyun varlığının oyuncunun giriş seçim eylemlerinden oluşan bir ağ paketi göndermek zorunda kaldığı bir durumda buluyordu ( buna "mega paket" diyoruz). Sunucu daha sonra tüm bu giriş eylemlerini doğru bir şekilde almakla kalmamalı, aynı zamanda bunları diğer tüm istemcilere de göndermelidir. Eğer 200 müşteriniz varsa, bu hızla bir sorun haline gelir. Sunucuya olan bağlantı hızla tıkanır, bu da paket kaybına ve yeniden talep edilen paketlerin art arda gelmesine neden olur. Giriş eyleminin geciktirilmesi, daha fazla müşterinin mega paket göndermesine neden olarak çığın daha da büyümesine neden olur. Şanslı müşteriler iyileşmeyi başarır; diğerleri düşer.

Megapack: Factorio 200 Oyunculu Çok Oyunculu Sorunu Nasıl Çözdü?
Sorun oldukça temeldi ve düzeltmem 2 haftamı aldı. Oldukça teknik bir konu, bu yüzden aşağıda ilginç teknik detayları açıklayacağım. Ancak öncelikle, 0.17.54 Haziran'da yayınlanan 4 sürümünden bu yana, geçici bağlantı sorunları karşısında çok oyunculu modun daha kararlı hale geldiğini ve gecikmeleri gizlemenin çok daha az hatalı hale geldiğini (daha az yavaşlama ve ışınlanma) bilmeniz gerekir. Ayrıca savaş gecikmesinin gizlenme şeklini de değiştirdim ve bunun işleri biraz daha pürüzsüz hale getireceğini umuyorum.

Çok Oyunculu Mega Paket - Teknik Detaylar

Basitçe ifade etmek gerekirse, bir oyunda çok oyunculu oyun şu şekilde çalışır: tüm istemciler oyunun durumunu simüle eder, yalnızca oyuncu girdisini alır ve gönderir ("giriş eylemleri" olarak adlandırılır), Giriş Eylemleri). Sunucunun asıl görevi transfer etmektir. Giriş Eylemleri ve tüm istemcilerin aynı eylemleri aynı saat döngüsünde gerçekleştirdiğini kontrol edin. Bununla ilgili daha fazla bilgiyi yazıda okuyabilirsiniz FFF-149.

Hangi eylemlerin gerçekleştirileceğine sunucunun karar vermesi gerektiğinden, oyuncunun eylemleri yaklaşık olarak şu yol boyunca hareket eder: oyuncu eylemi -> oyun istemcisi -> ağ -> sunucu -> ağ -> oyun istemcisi. Bu, her oyuncunun eyleminin yalnızca ağ üzerinde bir gidiş-dönüş yaptıktan sonra gerçekleştirileceği anlamına gelir. Bu nedenle oyun son derece yavaş görünüyordu, bu nedenle çok oyunculu modun oyuna dahil edilmesinden hemen sonra gecikmeleri gizlemek için bir mekanizma tanıtıldı. Gecikmeyi gizlemek, diğer oyuncuların eylemlerini ve sunucunun kararlarını hesaba katmadan oyuncu girişini simüle eder.

Megapack: Factorio 200 Oyunculu Çok Oyunculu Sorunu Nasıl Çözdü?
Factorio'nun bir oyun durumu var Oyun Durumu kartın, oyuncunun, varlıkların ve diğer her şeyin tam durumudur. Sunucudan alınan eylemlere dayalı olarak tüm istemcilerde deterministik olarak simüle edilir. Oyun durumu kutsaldır ve sunucudan veya başka bir istemciden farklılaşmaya başlarsa senkronizasyon bozulması meydana gelir.

Ancak Oyun Durumu bir gecikme durumumuz var Gecikme Durumu. Temel durumun küçük bir alt kümesini içerir. Gecikme Durumu kutsal değildir ve yalnızca oyuncu girdilerine dayalı olarak oyun durumunun gelecekte nasıl görüneceğine dair bir resmi temsil eder Giriş Eylemleri.

Bu amaçla oluşturulanların bir kopyasını saklıyoruz. Giriş Eylemleri gecikme kuyruğunda.

Megapack: Factorio 200 Oyunculu Çok Oyunculu Sorunu Nasıl Çözdü?
Yani, müşteri tarafında sürecin sonunda resim şuna benzer:

  1. Uygulamak Giriş Eylemleri tüm oyuncular Oyun Durumu bu giriş eylemlerinin sunucudan alınma şekli.
  2. Gecikme kuyruğundaki her şeyi kaldırıyoruz Giriş Eylemlerisunucuya göre zaten uygulanmış olan Oyun Durumu.
  3. kaldırmak Gecikme Durumu ve tamamen aynı görünecek şekilde sıfırlayın Oyun Durumu.
  4. Gecikme kuyruğundaki tüm eylemleri şuraya uyguluyoruz: Gecikme Durumu.
  5. Verilere dayalı Oyun Durumu и Gecikme Durumu Oyunu oyuncuya aktarıyoruz.

Bütün bunlar her ölçüde tekrarlanıyor.

Çok zor? Rahatlamayın, hepsi bu değil. Güvenilmez İnternet bağlantılarını telafi etmek için iki mekanizma oluşturduk:

  • Kaçırılan onay işaretleri: sunucu buna karar verdiğinde Giriş Eylemleri Oyunun ritmine göre idam edilecek, eğer alamadıysa Giriş Eylemleri bazı oyuncular (örneğin, artan gecikme nedeniyle), beklemeyecek, ancak bu müşteriye "Senin durumunu dikkate almadım" diye bilgi verecektir. Giriş Eylemleri, onları bir sonraki çubuğa eklemeye çalışacağım." Bu, bir oyuncunun bağlantısındaki (veya bilgisayarındaki) sorunlar nedeniyle harita güncellemesinin diğer herkes için yavaşlamaması için yapılır. şunu belirtmekte yarar var Giriş Eylemleri göz ardı edilmez, sadece bir kenara bırakılır.
  • Tam gidiş-dönüş gecikmesi: Sunucu, her istemci için istemci ile sunucu arasındaki gidiş-dönüş gecikmesinin ne kadar olduğunu tahmin etmeye çalışır. Her 5 saniyede bir, gerekiyorsa (bağlantının geçmişte nasıl davrandığına bağlı olarak) istemciyle yeni bir gecikme süresi üzerinde anlaşır ve buna göre gidiş-dönüş gecikmesini artırır veya azaltır.

Bu mekanizmalar kendi başlarına oldukça basittir, ancak birlikte kullanıldıklarında (ki bu genellikle bağlantı sorunlarında olur), kodun mantığını yönetmek zorlaşır ve birçok uç duruma neden olur. Ayrıca bu mekanizmalar devreye girdiğinde sunucu ve gecikme kuyruğunun özel düzenlemeyi doğru şekilde uygulaması gerekir. Giriş Eylemi adlı Sonraki Tick'te Hareketi Durdurun. Bu sayede bağlantıda sorun olması durumunda karakter kendi başına (örneğin trenin önünde) koşmayacaktır.

Şimdi size varlık seçiminin nasıl çalıştığını açıklamamız gerekiyor. Aktarılan türlerden biri Giriş Eylemi varlık seçim durumundaki bir değişikliktir. Herkese, oyuncunun hangi varlığın üzerine geldiğini söyler. Tahmin edebileceğiniz gibi bu, istemciler tarafından gönderilen en yaygın giriş eylemlerinden biridir; bu nedenle bant genişliğinden tasarruf etmek için bunu mümkün olduğunca az yer kaplayacak şekilde optimize ettik. Çalışma şekli, her varlık seçildiğinde mutlak, yüksek hassasiyetli harita koordinatlarını depolamak yerine oyunun önceki seçime göre düşük hassasiyetli göreceli uzaklığı depolamasıdır. Bu işe yarar çünkü fare seçimleri önceki seçime çok yakın olma eğilimindedir. Bu iki önemli gereksinimi ortaya çıkarmaktadır: Giriş Eylemleri Asla atlanmamalı ve doğru sırayla tamamlanmalıdır. Bu gereksinimler karşılanır Oyun Durumu. Ama görevden beri Gecikme durumu Oyuncu için "yeterince iyi görünme" durumunda, gecikme durumundan memnun değiller. Gecikme Durumu hesaba katmaz birçok uç durum, saat döngülerinin atlanması ve gidiş-dönüş iletim gecikmelerinin değiştirilmesiyle ilişkilidir.

Bunun nereye varacağını zaten tahmin edebilirsiniz. Sonunda megapack sorununun nedenlerini görmeye başlıyoruz. Sorunun kökü, varlık seçim mantığının şunlara dayanmasıdır: Gecikme Durumuve bu durum her zaman doğru bilgiyi içermez. Bu nedenle, bir megapaket şunun gibi oluşturulur:

  1. Oynatıcının bağlantı sorunları var.
  2. Saat döngülerini atlamaya ve gidiş-dönüş iletimdeki gecikmeyi düzenlemeye yönelik mekanizmalar devreye giriyor.
  3. Gecikme durumu kuyruğu bu mekanizmaları dikkate almaz. Bu, bazı eylemlerin zamanından önce kaldırılmasına veya yanlış sırada gerçekleştirilmesine neden olarak hatalı işlemlere neden olur. Gecikme Durumu.
  4. Oyuncunun bir bağlantı sorunu var ve sunucuya yetişmek için 400'e kadar döngü simülasyonu yapıyor.
  5. Her onay işaretinde varlık seçimini değiştiren yeni bir eylem oluşturulur ve sunucuya gönderilmek üzere hazırlanır.
  6. İstemci, sunucuya 400'den fazla varlık seçimi değişikliğinden oluşan mega bir yığın gönderir (ve diğer eylemlerle birlikte: çekim durumları, yürüme durumları vb. de bu sorundan muzdariptir).
  7. Sunucu 400 giriş eylemi alır. Herhangi bir giriş eyleminin atlanmasına izin verilmediğinden, tüm istemcilere bu eylemleri gerçekleştirme emri verir ve bunları ağ üzerinden gönderir.

Buradaki ironi, bant genişliğinden tasarruf etmek için tasarlanmış bir mekanizmanın sonunda devasa ağ paketleri oluşturmasıdır.

Güncelleme ve biriktirme kuyruğu desteğinin tüm uç durumlarını düzelterek bu sorunu çözdük. Her ne kadar biraz zaman alsa da, sonunda hızlı hacklere güvenmek yerine doğru şekilde yapmaya değerdi.

Kaynak: habr.com

Yorum ekle