Kalıcı veriler, oyun oturumları arasında her bir oyuncuya ait verileri takip edip kaydetmeni sağlar. Kalıcı veriler, her bir oyuncunun profili veya istatistikleri gibi verilerinin Verse’te depolanmasıyla çalışır. Bu veriler daha sonra verilerin değeri her değiştiğinde güncellenebilir. Bu veriler kalıcı olduğundan oyun oturumları genelinde kalıcı olacak ve oyuncu oyunda çevrimiçi olduğunda kullanılabilir olacaktır. Daha fazla bilgi için Verse'te Özel Kalıcı Veriler Kullanmak kısmına bakabilirsin.
Bu sayfada, Verse’te kalıcı verilerle çalışırken kullanılan en iyi uygulamaların bazıları ele alınmaktadır.
Daha Sonra Yeni Alanlar Eklemek İçin Sınıfları Kullan
Şu anda, adanı yayınladıktan sonra değiştirebileceğin tek kalıcı veri türü, yeni alanların varsayılan değerlere sahip olması koşuluyla sınıf türüdür. Yeni alanların varsayılan değerlere sahip olması, önceki sürümde yer alan kaydedilen veriler yüklenirken yeni alanlar ile bunların varsayılan değerlerinin de yükleneceği anlamına gelir.
Aşağıdaki kalıcı verilere sahip bir projeyi yayınlama örneğine bakalım.
player_profile_data := class<final><persistable>:
Class:player_class = player_class.Villager
XP:int = 0
Rank:int = 0Proje yayınlandığı ve canlı olduğu için oyunu oynamış olan oyuncular için onlarla ilişkilendirilmiş bu kalıcı veriler mevcut olacaktır. Oyuncu profili verilerine görev sayısı ve geçmişi gibi daha fazla alan eklediysek kalıcı veriler güncellenen projede aşağıdaki gibi görünebilir.
player_profile_data := class<final><persistable>:
Class:player_class = player_class.Villager
XP:int = 0
Rank:int = 0
CompletedQuestCount:int = 0
QuestHistory:[]string = array{}player_profile_data sınıfının ilk sürümüyle oynayan tüm oyunculara ait kalıcı veriler artık yeni alanları içerecektir:
Belirtilen varsayılan değer olan
0değerine sahipCompletedQuestCount.Belirtilen varsayılan değer olan boş bir dize dizisine sahip
QuestHistory.
Bunun işe yaramasının nedeni, yeni alanların, verilerin eski sürümünü güncelleyebilmesi için bu yeni alanlar için varsayılan değerler sağlanmış olmasıdır.
Bir proje yayınlandıktan sonra yalnızca sınıflar güncellenebileceğinden, modül kapsamındaki tüm weak_map değişkeninin değer türü olarak sınıf kullanmanı önemle tavsiye ederiz.
Kalıcı bir sınıfın nasıl oluşturulacağına dair daha ayrıntılı bilgi için Kalıcı Türler kısmına bakabilirsin.
Kısmi Güncellemeler İçin Oluşturucular Kullanma
Sınıflar kullanıyorsan güncellenmiş durumu içeren sınıfının yeni bir örneğini oluşturmak için bir oluşturucu kullanmanı öneririz, çünkü oluşturucular sınıfların kısmi güncellemelerini yapmana olanak tanır.
Aşağıdaki örnek, PlayerProfileDataMap’i nasıl güncelleyebileceğini göstermektedir. GrantXP() fonksiyonu, belirtilen oyuncunun geçerli verilerini alır ve ardından bu oyuncunun profil verilerinin yeni bir sürümünü oluşturmak için MakePlayerProfileData() oluşturucusunu çağırır. Oyuncunun kaynak verileri, yeni TP değeriyle birlikte oluşturucuya iletildiği için yalnızca TP değeri güncellenecek, oyuncunun diğer tüm verileri ise aynı kalacaktır.
MakePlayerProfileData<constructor>(Src:player_profile_data)<transacts> := player_profile_data:
Version := Src.Version
Class := Src.Class
XP := Src.XP
Rank := Src.Rank
CompletedQuestCount := Src.CompletedQuestCount
QuestHistory := Src.QuestHistory
GrantXP(Agent:agent, GrantedXP:int):void=
if:
Önceki örnekte tek bir alanın nasıl güncelleneceği gösterilmişti ancak ihtiyacın olduğu kadar çok sayıda alanı şu şekilde güncelleyebilirsin:
set PlayerProfileDataMap[Player] = player_profile_data:
QuestHistory := UpdatedSaveData.QuestHistory
CompletedQuestCount := OldData.CompletedQuestCount + 1
MakePlayerProfileData<constructor>(OldData)Kalıcı Veriler İçin Sürüm Oluşturma
Daha önce bir oyuncu için kaydedilmiş verilere dair örneğin sürümünü tespit etmek için kalıcı sınıflarda sürüm oluşturma özelliğini kullanmanı öneririz. Kalıcı sınıf tanımın veya oyun mantığın zaman içinde değişirse sürümleri kullanarak geçişleri tespit edip uygulayabilirsin.
Kalıcı sınıfının sürümünü belirtmek için tamsayı veya dize değerlerini kullanabilirsin ancak verilerinin mevcut ve geçmiş sürümlerine yönelik referansları depolamak için seçenek değerlerini kullanmanı öneririz. Aşağıdaki kurulumu göz önünde bulundur:
var SavedPlayerData:weak_map(player, player_data) = map{}
# A player data class containing optional fields of versioned player data. Only one of these
# optional values should contain a real value at any given time.
player_data := class<final><persistable>:
V1:?v1_player_data = false
V2:?v2_player_data = false
# Original version of player data.
Burada player_data sınıfı, ilişkili veri sınıfının birinci ve ikinci sürümleri için v1_player_data ve v2_player_data sınıflarıyla temsil edilen seçenek değerlerini içerir. Oyuncuların kendileriyle ilişkili veri sürümlerinin birden fazla olmaması için V1 veya V2 sürümlerinden yalnızca biri ayarlanmalıdır.
Orijinal V1 oyuncu verileri, üç tamsayı alanı içerir. Verilerin V2 sürümü, Oynatma Süresi alanını kayan sayı olarak değiştirirken iki yeni alan ekler. Oynatma Süresi alanının türü V2 sürümünde değiştiğinden, eski V1 verilerine sahip tüm oyuncular için bu alanın dönüştürülmesi gerekecektir. Eski V1 verilerine sahip bir oyuncu bir deneyime katıldığında, onun eski verilerine dayalı yeni bir V2 veri sınıfı oluşturmak için yardımcı oluşturucu fonksiyonlarını kullanabilirsin:
# Create v1_player_data using existing v1_player_data.
MakeV1PlayerData<constructor>(SourceData:v1_player_data)<transacts> := v1_player_data:
XP := SourceData.XP
Rank := SourceData.Rank
Playtime := SourceData.Playtime
# Create v2_player_data using existing v2_player_data.
MakeV2PlayerData<constructor>(SourceData:v2_player_data)<transacts> := v2_player_data:
XP := SourceData.XP
Rank := SourceData.Rank
Adana katılan oyuncular için bir veri sıfırlamasını zorlamak istediğin zamanlar olabilir. Bu işlem, tüm oyuncular için “weak_map” içerisindeki kalıcı verilere ilişkin olarak varsayılan bir değer yeniden ataması yapılması ve sınıfın Sürüm alanının değiştirilmesiyle gerçekleştirilebilir. İsteğe bağlı sürümü oluşturulmuş veriler kullanırsan isteğe bağlı alanları false olarak ayarlayarak verileri sıfırlayabilirsin.
Oyuncu verilerinin zaten sıfırlanmış olup olmadığını öğrenmek için oyuncunun kalıcı verilerindeki Sürüm değerinin en son sürüm olup olmadığını kontrol edebilirsin.
Kalıcı Verilerin Sınırlar Dahilinde Olduğunu Test Etme
Güncellemen kalıcı verilerin toplam boyutunu etkileyebilecekse kalıcı verilerin hâlâ Verse’ün süreklilik sistemi kısıtlamalarına uyuyor olduğunu doğrulaman gerekir. Kalıcı verileri güncellemeye çalışırsan ve bu veriler boyut sınırlarını aşarsa Verse çalışma zamanı hatası alırsın. Daha ayrıntılı bilgi için Maksimum Kalıcı Obje Boyutu kısmına bakabilirsin.
Güncellemelerinin toplam boyutu nasıl etkilediğini FitsInPlayerMap() fonksiyonunu kullanarak kontrol edebilirsin.
Aşağıdaki örnekte kalıcı veriler bir dizeler dizisi içermektedir. Bu dizi, weak_map içerisinde depolanamayacak kadar büyürse (bu durum FitsInPlayerMap() başarısız olduğunda gerçekleşir) örnekte dizi boşaltılır ve diziye yalnızca en son kaydedilen öğe eklenir.
# Construct and return a new player_profile_data with updated quest history.
SetQuestHistory(Src:player_profile_data, NewQuestHistory:[]string)<transacts>:player_profile_data =
NewData:player_profile_data = player_profile_data:
MakePlayerProfileData<constructor>(Src)
QuestHistory := NewQuestHistory
# Set a player's quest history in the PlayerProfileDataMap.
RecordQuestHistory(Agent:agent, QuestHistory:string):void=
if:
CheckSaveDataForPlayer[Agent]
Adana Katılan Oyuncuya Tepki Verme
Adana yeni bir oyuncu katıldığında, bu oyuncu için kalıcı weak_map’e otomatik olarak bir giriş eklenmeyecektir. Bu girişi Verse’e eklemen gerekir.
Bunu yapmak için, oyuna her eriştiğinde oyuncunun zaten weak_map’te olup olmadığını kontrol edebilir veya oyuna bir oyuncunun katıldığı her durumda (bunu oyunun PlayerAddedEvent() olayına abone olarak öğrenebilirsin) weak_map’e varsayılan veriler ekleyebilirsin.
GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)
# Later in your file
OnPlayerAdded(Player:player):void=
if:
not PlayerProfileDataMap[Player]
set PlayerProfileDataMap[Player] = player_profile_data{}