Oyuncu Verileri ve Satın Alma Sistemleri

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Arka Plan

Roblox, veri depolarına aracılığıyla DataStoreService ile API'leri sunar. En yaygın kullanım durumu bu API'leri kaydetmek, yüklemek ve kopyalamak içindir. Yani, oyuncunun ilerleme, satın alma ve diğer oturum özellikleriyle ilgili verileri kaydetmek için ilgili veriyle etiketlenmiştir.

Roblox'daki çoğu deneyim, bir oyuncu veri sisteminin bir formunu uygulamak için bu API'leri kullanır. Bu uygulamalar yaklaşımları farklıdır, ancak genellikle aynı seti sorunları çözmeyi heder.

Sıradan Sorunlar

Aşağıda, en çok çözmeye çalıştığımız oyun verileri sistemlerinin bazılarının çözmeye çalıştığı problemlerin bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazılarının bazıları

  • Hafıza Erişiminde:: DataStoreService istekleri web isteklerini oluşturur ve hızlı olarak işlemez. Bu, oturum sunucugirişsel bir yükleme için uygun bir başlangıçtır, ancak oynanışnormal yükleme ve yazma iş

    • Bir oturumun başlangıcında ilk okuma
    • Oturumun sonunda nihai oturum
    • Düzenli aralıklarla senaryoda son yazın başarısız olduğu senaryoyu mitigasyon etmek için yazıyor
    • Bir satın alma işlemi sırasında verilerin kaydedilmesini sağlar
  • Verimli Depolama: Tüm bir oyuncunun seans verilerini tek bir tabloda depolamak, birçok değeri atomik olarak güncellemenizi ve daha az isteklerde aynı miktarda veri işlemesini sağlar. Ayrıca, değerlerinizin çarpışma riskini ortadan kaldırır ve işlemleri daha kolay hale getirir.

    Bazı geliştiriciler ayrıca kullanıcıların oluşturduğu büyük veri yapılarını sıkıştırmak için özel serileştirmeyi de uygulayabilir (genellikle oyun içi kullanıcı oluşturulmuş içerikleri kaydetmek için).

  • Replikasyon: Klientin bir oyuncunun verilerine düzenli erişimi gerekir (örneğin, UI'yi güncelleme). Klientin verilerini replikasyon etmek için genel bir yaklaşım, bu bilgileri her veri bileşeni için özelleştirilmiş replikasyon sistemleri oluşturmak zorunda kalmadan iletmenizi sağlar. Geliştiriciler genell

  • Hata Yönetimi: DataStores erişilemezse, çoğu çözüm bir tekrar denemesi mekanizması ve 'varsayılan' verilere dönüştürülmesi için bir çözüm mekanizması uygulayacaktır. Özel dikkat gerektirir, böylece geri verilen veriler 'gerçek' verilere üstesinden gelmez ve bu, oyuncuya açık şekilde iletilir.

  • Yeniden denemeler: Veri depoları erişilemezse, çoğu çözüm bir deneme mekanizması veya varsayılan verilere bir geçiş için bir çözüm için yeniden denemeyi destekler. Ayrıca, geçiş verilerinin "gerçek" verilere yazılmasını önlemek için özel dikkat etmeyi gerektirir.

  • Oturum kilidi: Tek bir oyuncunun verileri birden fazla sunucuda hafızanın içindeyse, bir sunucudaki bir oyuncu çıkışı gecikmiş olabilir. Bu, veri kaybı ve yaygın öğe tekrar yazma açığına yol açabilir.

  • Atomik Satın Alma İşlemleri:: Satın alma işlemlerini atomik olarak doğrula, ödüllendir ve alımların birden fazla kez kaybolmasını önlemek için kayıt altında tut.

Örnek Kod

Roblox, oyuncu veri sistemlerini tasarlamak ve oluşturmak için size yardımcı olmak için bir referans kodu sahiptir. Bu sayfanın geri kalanı, arka planı, uygulama ayrıntılarını ve genel notlarını inceleyecektir.


Studio'a modeli ithal ettikten sonra şu dizin yapısını görmelisiniz:

Explorer window showing the purchasing system model.

Arşitektür

Bu yüksek seviyeli grafik, örnekteki anahtar sistemlerini ve diğer deneyim bölümündeki kodla nasıl etkileşim kurduğunu gösterir.

An architecture diagram for the code sample.

Yeniden denemeler

Sınıf: DataStoreWrapper

Arka Plan

Tüm çıkartmalarınızı DataStoreService altında bir web isteği yaparak web isteğinizin başarılı olacağına dair garanti vermez. Bu durumda, DataStore yöntemleri hata verir ve bunları ele alabilirsiniz.

Veri depolama arızaları gibi bunları ele almaya çalışırsanız yaygın bir "oturttum" olabilir:


local function retrySetAsync(dataStore, key, value)
for _ = 1, MAX_ATTEMPTS do
local success, result = pcall(dataStore.SetAsync, dataStore, key, value)
if success then
break
end
task.wait(TIME_BETWEEN_ATTEMPTS)
end
end

Bu genel bir işlev için mükemmel bir tekrar deneme mekanizması olmasına rağmen, DataStoreService istekleri için uygun değildir, çünkü isteklerin sırasını garanti etmez. İsteklerin sırasını korumak önemlidir, çünkü DataStoreService istekleri devletle etkileşime girer. Aşağıdaki sen

  1. A isteği yapılır ve anahtarın değerini 1'e ayarlar.
  2. İstek başarısız olduğundan, 2 saniye içinde yeniden deneme planlanıyor.
  3. Yeniden deneme gerçekleşmeden önce, B'nin K değerini 2'ye ayarlar, ancak A'nın yeniden denemesi derhal bu değeri yazıyor ve K değerini 1'e ayarlar.

anahtardeğerinin en son sürümünde çalışmasına rağmen, UpdateAsync İsteklerinin işlenmesi hala geçersiz geçici devletleri önlemek için işlenmesi gerekir. UpdateAsync İsteklerinin işlenmesi hala geçersiz geçici devletleri

Oyuncu verilerimiz sistemi, DataStoreWrapper kullanır, bu da anahtar başına işlenmesi garanti edilen yeniden deneme sağlar.

Yaklaşım

An process diagram illustrating the retry system

DataStoreWrapper``Class.GlobalDataStore|DataStore yöntemlerine eşdeğer yöntemler sağlar: DataStore:GetAsync() , 0> Class.GlobalDataStore:SetAsync()

Bu yöntemler, çağrıldığında:

  1. İstek bir sıraya eklenir. Her anahtarın kendi sırası vardır, gdzie istekler seri olarak işlenir. İstek eden subprocess yanıtlanana kadar yayınlanır.

    Bu özellik ThreadQueue sınıfına dayanır, bu da bir coroutine'e dayanan görev planlayıcısı ve hız sınırıdır. Bir vaat döndürmek yerine, ThreadQueue şu andaki thread'i işlem tamamlandığına kadar yayınlandırır ve bir hata oluşursa hata ayılar. Bu, idmantik asenkron Lua modelleriyle daha

  2. Bir istek başarısız olursa, yapılandırılabilir bir üstel geri alma ile tekrar deneyin. Bu geri alma, sıraya gönderilen çağrının ardından için kuyrukta güvence edilmiştir, bu yüzden sıraya girecek bir sonraki isteğe kadar garanti edilmiştir.

  3. Bir istek tamamlandığında, istek metodu success, result şeklinde geri döndüğünde

DataStoreWrapper ayrıca, bir belirli anahtar için sırayı almak için yöntemleri gösterir ve stale istekleri temizler. Son seçenek özellikle sunucu kapatıldığında ve işleme sadece en son istekler olmadan herhangi bir istek olmadığında kullanışlıdır.

Kısıtlama

DataStoreWrapper Extreme senaryolardaki her veri depolama isteğinin (başarıyla veya başarısız) tamamlanmasına izin verilmesi gerektiğini takip eder, bununla birlikte, daha yeni bir istek bunu gereksiz kılarsa, stale istekler oyunun başlangıcı

  1. Bir isteğin sırayı terk etmeye güvenli olduğu için intuitif bir kurallar setine karar vermek zor. Aşağıdaki sırayı göz önünde bulundurun:

    Value=0, SetAsync(1), GetAsync(), SetAsync(2)

    Beklenen davranış şu ki GetAsync()``1 ı döndürür, ancak en son yapılandırma nedeniyle SetAsync() isteğini sıraya kaldırdığı için, 1> 01> döndürür.

    Mantıksal ilerleme, yeni bir yazma isteği eklenildiğinde, sadece en son okuma talepitibaren sadece kısa solgun istekleri günceller. UpdateAsync() , bu sistemin kullanılan tek işlem (ve bu sistemin hiç kullanılmayan tek işlem) olarak, her ikisi de okuma ve yazma için zorluklı olabilir

    DataStoreWrapper bir UpdateAsync() isteğinin okunup/yazılmasına izin verileceğini ve/veya yazılacağını belirtmenizi gerektirebilir, ancak bu, zaman öncesi olarak oyuncu veri sistemimizde okunabilir/yazılabilir olmaz (siege kilit mekanizmasının içinde ayrıntılı ol

  2. Sıraya çıktığından bu yana, bunun nasıl nasıl bu işlem işleneceğine karar vermek zor. Bir DataStoreWrapper isteği yapıldığında mevcut thread yanlış olarak kapatılır, tüm işlem tamamlandı

Sonuçta, basit yaklaşım (her talepişleyen) burada tercih edilir ve daha karmaşık sorunlar yaklaşıldığında daha açık bir ortam yaratır. Bu durumda, DataModel:BindToClose() ı

Oturum kilidi

Sınıf: SessionLockedDataStoreWrapperSessionLockedDataStoreWrapper

Arka Plan

Oyuncu verileri, sunucudaki hafızada saklanır ve sadece gerekli olduğunda yazılıp okunur. Web istekleri gerekli olduğunda anında okunur ve DataStoreService sınırlarını aşmayan yazılır.

Bu model aslında işlemesi için, bir servisin bir oyuncunun verilerini DataStore ile aynı anda yükleyebileceğinden çok önemlidir.

Örneğin, eğer sunucu A bir oyuncunun verilerini yüklerse, sunucu B sunucu A'nın kilidini açana kadar o verileri veri depolarından yükleyemez. Eğer kilit mekanizması yoksa, sunucu B, sunucu A'nın en son sürümünü memnuniyetle kaydederse, sunucu B'nin mem

Roblox sadece bir istemci'nin bir sunucuya sadece bir kere bağlanmasına izin verdiğini göz önünde bulundurarak, bir oturumun verilerinin bir sonraki oturum başladığında hep kaydedilmiş olacağını düşünemezsiniz. Aşağıdaki senaryolardan bazılarını dikkate alın, bir oyuncu sunucudan ayrılırsa:

  1. Server A, verilerini kaydetmek için bir DataStore isteği yapar, ancak istek başarısız olur ve birkaç tekrar denemesi gerekir. İtirme süresinde, oyuncu sunucuya katılır.
  2. Sunucu A çok fazla UpdateAsync() çağrısı yapar ve sınırlı bir şekilde işlem görür. Son kayıt isteği kuyruğa yerleştirilir. Sunucu isteği kuyruğa yerleştirilirken oyuncu sunucu B'ye katılır.
  3. A'daki bazı kodlar PlayerRemoving etkinliğine bağlı kalarak oyuncu verileri kaydedilmeden önce görüntülenir. Bu işlem tamamlandıktan önce oyuncu B'ye sunucuya katılır.
  4. Sunucunun A'nın performansı, oyuncu sunucuya B'ye katılana kadar son kaydın gecikmesine neden olur.

Bu senaryolar nadir olmalıdır, ancak meydana gel, özellikle bir oyuncu bir sunucudan başka birine hızlı bir şekilde bağlanır (örneğin, ışınlanırken). Bazı kötü niyetli kullanıcılar bu davranışı kötüye kullanmaya çalışabilirler (örneğin, ışınlanırken). Bu, öğe duplikasyonu e

oyuncuDataStore anahtarının ilk okunmasını sağlayarak bu zayıflığı giderir. Sunucu, sunucu atomu olarak anahtarın metnini aynı UpdateAsync() çağrısında ilk kez okur. Eğer bu kilit değeri me

Yaklaşım

An process diagram illustrating the session locking system

SessionLockedDataStoreWrapper``DataStoreWrapper sınıfının etrafında bir meta-Wraper'dir. DataStoreWrapper Queue ve tekrar deneyin işlevlerini sağlar, bu da 0> SessionLockedDataStore0>'ın oturum kilitlenmesiyle desteklenir.

SessionLockedDataStoreWrapper her

Dönüşüm işlevi her istek için UpdateAsync için şu işlemleri yerine getirir:

  1. Anahtarın erişime güvenli olduğunu doğrular, eğer değilse işlemi terk eder. "Güvenli erişim" ifadesi:

    • anahtarmetadatosu, kilit süresi dolduğundan daha az bir süre önce güncellenmiş olmayan bir LockId değeri içermez. Bu, kilit yerleştiren başka bir sunucunun saygısını gösterir ve kilit süresi dolduğunda görmezden gelir.

    • Eğer bu sunucu daha önce anahtarın metadatına kendi değerini LockId yerleştirmişse, bu değer hala anahtarın metadatında bulunur. Bu, bir başka sunucunun kilidini (genellikle süresi dolduğu için veya zorla) aldı

  2. Class.GlobalDataStore:UpdateAsync()|UpdateAsync``Class.GlobalDataStore|DataStore işlemini yerine getirir. Örneğin, SessionLockedDataStoreWrapper 0> function(value) return value bitir0> ile çevirir.

  3. İstekte geçen talepbağlı olarak, UpdateAsync şunu kilitler veya açar:

    1. Anahtar kilitli olacaksa, UpdateAsync , anahtarın metadılarındaki LockId'yı bir GUID olarak kaydeder. Bu GUID, sunucunun hafızasında depolanır, böylece kilidi sonraki kez er

    2. Anahtar kilidi açılacaksa, UpdateAsync anahtariçindeki LockId kaldırır.

Aşağıdaki DataStoreWrapper içine özel bir tekrar deneme eşenekleri geçilir, böylece işlem 1 adımda kilitlenen oturum nedeniyle iptal edilirse tekrar denemesi yeniden deneme işlemi yapılır.

Oyuncu veri sisteminin oturum kilidi için ses kilidi rapor etmesi durumunda alternatif bir hata rapor etmesine izin veren özel bir hata mesajı da tüketiciye döndürülür.

Kısıtlama

Oturum kilit mekanizması, bir anahtarın kilidini her zaman bir anahtarın kilidini açtığında, bir oturum kilit için her zaman bir anahtar serbest bırakarak güvenilir. Bu, bir anahtarın PlayerRemoving veya Class.DataModel:BindToClose()|BindToClose() içindeki bir bileşen olarak</

Ancak, kilidi bazı durumlarda başarısız olabilir. Örneğin:

  • Sunucu çöktü veya DataStoreService tüm anahtariçin işlevsiz hale geldi.
  • Aynı mantıksal bir hata veya benzer bir hata nedeniyle, anahtarın kilidini açma talimatı yapılmadı.

Bir anahtarın kilidini korumak için, onu belleğe yükleninceye kadar düzenli olarak erişmelisiniz. Bu, normalde oyunun arka planındaki otomatik kaydetme çevirimi içinde çalışan bir otomatik kaydetme çevirimi olarak yapılır, ancak bu sistem ayrıca manuel olarak yapmanız gereken durumda bir refreshLockAsync metodu da gösterir.

Kilit süresi dolmasına rağmen güncellenmediğinde, herhangi bir sunucu kilidi ele geçirebilir. Eğer farklı bir sunucu kilidi alırsa, mevcut sunucunun okuması veya yazması gereken anahtarı okuması veya yazması gerekir.

Geliştirici Ürün İşlemesi

Singleton: ReceiptHandler

Arka Plan

ProcessReceipt çağrısı, satın alma işleminin nihayetlenmesi için kritik bir işi yerine getirir. ProcessReceipt , sehr belirli senaryolarda çağrılır. Satın alma garantilerinin seti için, MarketplaceService.ProcessReceipt görün.

Bir satın alma işleminin tanımı deneyimler arasında farklı olabilir, ancak aşağıdaki kriterleri kullanırız

  1. Satın alma daha önce işlenmedi.

  2. Satın alma işlemi mevcut oturumda yansıtılır.

  3. Satın alma işlemi bir DataStore 'e kaydedildi.

    Her satın alma, hatta tek kullanımlık malzemeler bile, DataStore içinde yansıtılmalıdır, böylece kullanıcıların oturum verileriyle satın alma geçmişi dahil edilir.

Bu, PurchaseGranted işlemini geri döndürmeden önce aşağıdaki işlemleri yapmanız gerekir:

  1. PurchaseId ile ilgili olmayan bir kaydın olup olmadığını doğrula.
  2. oyuncuiç bellekli verilerinde satın alma işlemini ödüllendir.
  3. oyuncuPurchaseId kaydedilen PurchaseId adlı kaydı işleyin.
  4. Oyuncunun DataStoreClass.GlobalDataStore|DataStore 'a yazın.

Oturum kilidi, bu akışı basitleştirir, çünkü artık şu senaryolardan endişelenmenize gerek yok:

  • Mevcut sunucudaki hafıza oyuncu verileri potansiyel olarak güncelli olabilir, bu nedenle DataStore tarihini doğrulmadan önce PurchaseId dan en son değer alınması gerekir
  • Aynı sunucuda gerçekleştirilen aynı satın alma için çağrı, tüm PurchaseId geçmişini okumak ve yazmak ve güncellenen oyuncu verilerini satın alma işlemini atomik olarak kaydetmek gerekir, böylece yarış koşullarını önlemek için

Oyuncunun DataStore 'ine yazma denemesi başarılı olursa, diğer sunucularda oyuncunun DataStore 'ine hiç yazılmaz veya yazılır. Bu, verilerin bu sunucuda yüklenip kaydedilmesi sırasınd

Yaklaşım

ReceiptProcessor iletişim kutusunun içindeki yorumlar yaklaşımı vurguluyor:

  1. oyuncuverilerinin bu sunucuda yüklendiğinden ve herhangi bir hata olmadan yüklendiğinden emin olun.

    Bu sistem oturum kilidi kullanıyor, bu nedenle bu kontrol ayrıca hafıza içindeki verilerin en son sürüm olduğunu doğruluyor.

    Oyuncu'nun verileri henüz yüklenmedi (bu, bir oyuncu bir oyuna katıldığında beklenen şeydir), oyuncu'nun verilerini bekleyin. Ayrıca, oyuncu'nun verilerini ayrıldığından beri bu satın alma işleminin bu sunucuda yeniden çağrılmasının önlenmesi için sistem dinlenir (bu, süresiz olarak yeniden çağrılmasını

  2. PurchaseId ile ilgili olarak oyuncu verilerinde işlenmediğinden emin olun.

    Oturum kilidi nedeniyle, sistemin belleğindeki PurchaseIds matrisi en yeni versiyonu kaydediyor ve PurchaseId içine k

  3. Satın almayı "ödüllendirmek" için bu sunucudaki Oyuncu Verilerini yerel olarak güncelle.

    ReceiptProcessor genel bir çağrı yaklaşımı kullanır ve her DeveloperProductId için farklı bir çağrı atar.

  4. PurchaseId ı depolamak için bu sunucudaki oyuncu verilerini yerel olarak güncelle

  5. İçerikteki verileri DataStore 'a kaydetmek için bir istek gönderin, PurchaseGranted ise NotProcessedYet eğer istek başarılı ise 2>İşlenmedi2> döndürür.

    Bu kaydetme isteği başarısız olursa, oyuncunun iç bellek oturum verilerini kaydetme isteği daha sonra başarılı olabilir. Sonraki ProcessReceipt çağrısında, adım 2 bu durumu ele alır ve PurchaseGranted döndürür.

Oyuncu Verileri

Kısayolluklar: PlayerData.Server > , PlayerData.Client >

Arka Plan

Oyun kodu için bir arayüz sağlayan modüller Roblox deneyimlerinde yaygındır. Bu bölüm PlayerData.Server ve PlayerData.Client ile ilgilidir.

Yaklaşım

PlayerData.Server ve PlayerData.Client takip edilenkonuları işleyin:

  1. oyuncuverilerini hafıza içine yükleniyor, yüklemeyi başarısız yapan durumlarda dahil olmak üzere
  2. Oyuncu verilerini sorgulamak ve değiştirmek için bir arayüz sağlamak
  3. oyuncuverilerinde değişiklikleri kaydederek, kullanıcı koduna erişebilmesi için
  4. Hataları gösterebilmesi için kliye yükleme veya kaydetme hatalarını yeniden oluşturuyor
  5. Oyuncunun verilerini periyodik olarak kaydetme, oyuncu ayrıldığında ve sunucu kapandığında

Oyuncu Verileri Yükleniyor

An process diagram illustrating the loading system
  1. SessionLockedDataStoreWrapper data mağaza'a bir getAsync isteği yapar.

    Eğer bu istek başarısızsa, varsayılan veriler kullanılır ve profil "hata" olarak işaretlenir, böylece veriler daha sonra veri depolarına yazılmaz.

    Alternatif bir seçenek oyuncuyu atlamak, ancak oyuncunun varsayılan verilerle oynamasını sağlamak ve oyunu çıkarmak yerine girişimden ayrılmasını temizlemek öneririz.

  2. Bir başlangıç ​​uyanıklığı, PlayerDataClient ile yüklenen verileri ve hata durumunu içeren bir özgürlükçü yük içerir.

  3. Oyuncu için waitForDataLoadAsync kullanılarak herhangi bir bağlantı askıya alınır.

Sunucu Kodu için Bir Arayüz Sağlamak

  • PlayerDataServer bir teknik olup aynı çevreçalışan herhangi bir sunucu kodu tarafından gerekli ve erişilebilir.
  • Oyuncu verileri bir anahtar ve değer sözlüğüne düzenlenmiştir. Bu değerleri sunucudaki setValue , getValue , updateValue ve 2>Player2> yöntemleri aracılığıyla manipüle edebilirsiniz. Bu yöntemlerin hepsi, verileri yüklemeyi gerektirmeyen bir şekilde çalışır.
  • hasLoaded ve waitForDataLoadAsync yöntemleri, verilerin yüklendiğinden emin olmak için kullanılabilir. Bu, diğer sistemlerin başlatılmasından önce yükleme ekranında bir kez yapılmasını öneririz.
  • Bir hasErrored yöntemi, oyuncunun başlangıç ​​yüklemesi başarısız olduğunda sorabilir, böylece varsayılan verileri kullanır. Bu yöntemi hasErrored olmadan oyuncu satın alma işlemlerine izin vermeden önce kontrol edin, çünkü satın alma işlemleri başarısız olabilir.
  • Bir playerDataUpdated sinyali, player , key ve 1> value1> ile herhangi bir anda değiştirilmiş oyuncunun verilerini değiştirir. Bir kişisel sistem buna abone olabilir.

Değişiklikleri Klient'e Replikasyon

  • Oyuncu verilerinde herhangi bir değişiklik PlayerDataServer içindeki herhangi bir değişiklik PlayerDataClient içine kopyalanır, aksi takdirde setValueAsPrivate kullanılarak özel olarak etiketlenmiş değilse
    • setValueAsPrivate kullanıcıya gönderilmeyecek anahtarları ifade eder
  • PlayerDataClient , bir anahtarın değerini alma (alın) ve güncellendiğinde ateşlenen sinyali içerir. A hasLoaded metodu ve bir loaded sinyali de dahil edilmiştir, böylece kliğın sistemlerini başlatmadan önce verileri yükleme ve kopyalama için bekleyebilir
  • PlayerDataClient bir teknik özellik oluşturucudur ve aynı çevreçalışan herhangi bir kod tarafından gerekebilir ve erişilebilir

Client'a Hataları Replikasyon

  • Oyuncu verilerinin kopyalanması veya yüklenmesi sırasında PlayerDataClient ile karşılaşılan hata durumları.
  • Bu bilgiyere getLoadError ve getSaveError yöntemleri ile, loaded ve 1>Saved1> sinyalleri ile erişin.
  • İki tür hata vardır: DataStoreError (DataStoreService isteği başarısız) ve SessionLocked (1> Oturum kilidi1> görünüyor).
  • Bu etkinlikleri kullanarak müşteri satın alma ekranlarını devre dışı bırakın ve uyarı diyaloglarını uygulayın. Bu görsel bir öğretici diyalog gösterir:
A screenshot of an example warning that could be shown when player data fails to load

Oyuncu Verileri Kaydediliyor

A process diagram illustrating the saving system
  1. Oyuncu oyundan ayrıldığında, sistem aşağıdaki adımları izler:

    1. Oyuncunun verilerini veri mağazayazmak güvenli olup olmadığını kontrol edin. Güvenli olmayan senaryolarda oyuncunun verileri yüklemeyi başaramaz veya hala yükleniyor.
    2. Mevcut veri değerini hafıza ve oturum kilidini kaldırmak için şu şekilde bir istek gönderin: SessionLockedDataStoreWrapper
    3. oyuncuverilerini (ve diğer değişkenleri, örneğin metadatlar ve hata durumları) sunucudaki hafızadan temizler.
  2. Düzenli bir döngüde, sunucu her oyuncunun verilerini veri depolarına yazıyor (kaydedilmesi güvenli olduğu takdirde). Bu hoşgeldiniz geçersizliği, bir sunucu kaybı durumunda kayıp olma riskini azaltır ve ayrıca oturum kilidini korumak için gereklidir.

  3. Sunucunun kapatılması istenildiğinde, şunu BindToClose çağrısında görür:

    1. Bir istek, bir oyuncunun sunucuda herhangi bir verisini kaydetmesini sağlar, bir oyuncu sunucudan ayrıldığında normalde işlenen süreci izleyerek. Bu istekler paralel olarak yapılır, çünkü BindToClose çağrılarının sadece 30 saniye süresi vardır.
    2. Kayıtları hızlandırmak için, her bir anahtarın sırasındaki tüm diğer istekler DataStoreWrapper (görüntülenen Yeniden deneyin) ile temizlenir.
    3. Çağrı, tüm isteklerin tamamlanana kadar iade edilmez.