Giriş yapmış tüm karakterleri MMO'larda düzenli aralıklarla kaydetmenin performans avantajı nedir?


26

MMORPGS'nin çoğunda her X saatte bir kez tüm karakterleri kurtaracak bir Worldsave sistemi var. Sanırım sebebi performans. Öyleyse neden bağlantı kesilmesinde bir karakter kaydetmekten daha iyi, performans daha akıllıca?


34
Performans için değil; Doğruluk için biraz performanstan ödün vermektir , bu daha önemlidir.
Mason Wheeler,

Burada zaman gerçekten herhangi bir rol oynuyor mu? AFAIK, bir mmo içindeki her eylem anında kaydedilir. Bir öğe alırsınız ve bu öğe hesabınıza gecikmeden sunucuya eklenir, aksi takdirde sunucu bunu yaptığınızı hatırlatmak zorunda kalır ve 5 dakika sonra bunun yararı olmaz. Veya müşteri bunu 5 dakika sonra hatırlamak ve göndermek zorunda kalır, bu da sizi hacklemeye açar, çünkü o 5 dakika içinde herkes gönderilecek verileri değiştirebilir / ekleyebilir.
Umarım yardımcı olur

4
@HopefullyHelpful Hayır, bu doğru değil. Bir MMO’daki her işlem hemen bellekte , ancak bu geçici. Her şeyi doğrudan kalıcı depolamaya kaydetmek, SSD'lerde bile çok pahalı. Doğrudan bir veritabanına kaydedilmiş oyunlarda bile, veritabanının kendisi bu verileri hemen diske kaydetmez (veya en azından yalnızca bir işlem günlüğünü kaydeder, tutarlı verileri değil - bu bir çöküşte yeniden oluşturulması gerekir ve biraz zaman). Ancak bağlantı kesilmekten tasarruf etmek, başka bir nedenden ötürü kötü bir fikirdir - tutarlılık.
Luaan

1
Bu sorunun, karakterlerin gerçek zamanlı olarak, aralıklarla kaydedilmesinin performans yararının ne olduğu boyunca daha fazla olacağını düşünmüştüm.
Anthony,

2
@Luaan: Her durum değişikliğini, kalıcı sabit depolama birimine, hatta mekanik HDD'lerde bile kaydetmek mümkün. (Meşgul sunucularda birkaç tane gerekebilir). Hile etmektir değil bireysel nesneleri güncelleyin. Bunun yerine, bir işlem günlüğünü kaydedersiniz "Player (A) .Inventory + = Object (B)`. Periyodik olarak tam halini temizlersiniz. Kurtarmak için, en son tam kaydı yeniden yükler ve işlem günlüğünden en yeni işlemleri uygularsınız. .. 'tek dosya sırayla yazıyoruz, sen mekanik HDD için maksimum performans ulaşmak Ama büyüklüğünde makul işlem günlüğü tutmak için, tam periyodik kaydeder gerek
MSalters

Yanıtlar:


66

Bu performans için değil. Bu bir güvenli değil. Dünya birkaç dakikada bir tasarruf ederse, o zaman sunucuya bir şey olursa ve kapanırsa herkes yalnızca birkaç dakikalık ilerlemeyi kaybeder.

Bağlantı kesme işleminden tasarruf ederek, sunucunun bir sorunu varsa, herkes oturum açtıktan sonra yaptıkları her şeyi kaybeder. Özellikle uzun oyun oturumlarında olanlar için (MMO'larda olduğu gibi), önemli miktarda veri kaybedeceklerdir.

Toplu veri kaybı riskini ortadan kaldırmak için küçük bir performanstan ödün veriyorlar.

Elbette, oynatıcı verilerini istemci makinelerde kolayca depolayabilir ve ağ trafiğini azaltabilirsiniz. Buradaki sorun, hacklemeye açık olmasıdır. Bir kişi nasıl hile yapılacağını öğrendiğinde, paylaşır ve herkes yapar.


EDIT: @Philipp'in belirttiği gibi , bu aynı zamanda eşyaların kopyalanmasını engeller . Bir sunucu çökmesinden önce bir işlem yapılırsa ve bir kişi çökmeden önce oturumu kapatırsa, bağlantı kesme tasarruflu bir sistemde, her iki oyuncu da en son çıktıklarında öğeyi siler veya çoğaltır.


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Josh,

5

Sadece bağlantıyı kesene kaydedilen ilk sistemler, oyuncu aktifken periyodik olarak tasarruf etme eğilimindeydi. Bu sistemlerde, tipik olarak ÇAMURLAR (Çok Kullanıcı Zindanlar), karakter, periyodik olarak bir dosyaya bırakılana kadar bellekte tutuldu.

Bu, eğer bir kullanıcının "kamp yapmadan" bağlantısı kesilirse, genellikle kendilerini birkaç oda ötede buldukları ve en son kurtardıklarından bir sürü ganimet, XP vb. Kaybettikleri anlamına geliyordu. Bu bakımdan, konsol RPG'lerinin bugün nasıl oynandığı gibi davrandı (konsolu kapatmadan oyununuzu kaydetmeniz veya son kaydettiğinizden beri her şeyinizi kaybetmeniz gerekiyor).

Sistem amaçlanan amacı için çalıştı, çünkü karakterler birbirleriyle etkileşimde bulunabilecekleri bir "posta" sistemi dışında birbirleriyle etkileşime giremediler. Eşyaları kaybetme ve ilerleme şansı oldukça belirgin olma eğilimindeydi, ancak çoğu durumda sadece bir karakteri etkiledi.

Worldsave özelliği ortaya çıktı çünkü karakterler sonunda birbirleriyle doğrudan etkileşimde bulunabiliyorlardı, bu yüzden oynayan karakterlerin hepsinin tutarlı bir durumda olması gerekiyordu, yoksa eşyaların kopyalanması ve silinmesi ortaya çıkabilirdi. Bu MUD senaryosunda bir problem değildi, çünkü sistemi madde veya para birimi çoğaltmasıyla sonuçlanacak şekilde kötüye kullanmak zordu, ancak erken MMO MUD'larında yapmak inanılmaz derecede kolaydı. Oyuncu A, oyuncu B'ye bir öğe verir, oyuncu B tasarruf eder ve oyuncu A, kaydetmeden bağlantıyı keser. Anında çoğaltma.

Worldsave bir performans avantajı değil , hile yapmayı önlemek için tasarlanmıştır. Worldsave olayının kelimenin tam anlamıyla duyurulduğu sistemler üzerinde oynadığımı hatırlıyorum ve sunucu tüm dosyaları güncellerken genellikle tüm sistemi bir dakika bekletti. Bu hile yapmayı engellerken, bu sistem kullanıcıları için pek uygun değildi.

Bu bizi şu anki durumlara götürür. Bugün dünyasal tip fonksiyonlarını kullanmıyoruz. Veritabanları kullanıyoruz. Bu, çoğaltma ve silme işlemlerinin mümkün olduğunca en aza indirgenmesini sağlamamızı sağlar. Karakterler bir veritabanında kayıtlar olarak bulunur ve oyuncular arasındaki her işlem gerçek bir veritabanı işlemidir; ya eylem tamamen taahhüt edildi ya da geri alınacak.

Sistemdeki alışılmadık hataları engelleyerek, tek tek karakter dosyalarını kaydetmenin (hızlı zaman kazanma) ve dünya tasarruflarının faydalarını (aldatma yok), ikisinin dezavantajını (önemli ilerleme ve ürün çoğaltmasını kaybetmeden) elde etmenin faydalarını elde edersiniz.

Modern bir MMO tasarlarken bir veritabanında saklı yordamlar oluşturmak ve bu yordamları işlem yapmak için kullanmak istersiniz. Örneğin, iki oyuncu arasında bir işlem yaparken aşağıdaki gibi görünebilir:

start transaction;
insert into inventory (playerid, itemid) values (111, 222);
delete from inventory where playerid=111 and itemid=444;
insert into inventory (playerid, itemid) values (333, 444);
delete from inventory where playerid=333 and itemid=222;
commit;

(Not: Bu SQL, pratik bir şekilde yazılmaz ve sadece bir örnek olması içindir).

Bu şekilde, taahhütten önce bir çökme olursa, sistem, oyuncu 111 ve oyuncu 333'ün hala orijinal eşyalara sahip olduğu bir duruma geri döner, ancak taahhütten sonra ticaret tamamlanır. Kopyalama imkanı yoktur, çünkü karakterler aynı anda, veritabanının güvence altına aldığı şekilde kaydedilir.

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.