I dati persistenti ti consentono di tracciare e salvare i dati in base al giocatore nelle diverse sessioni di gioco. I dati, per esempio il profilo o le statistiche, sono persistenti mediante l'archiviazione in base al giocatore in Verse. I dati possono poi essere aggiornati ogni volta che cambiano i valori. Dato che i dati sono persistenti, vengono portati da una sessione di gioco all'altra e sono disponibili ogni volta che i giocatori sono online. Per maggiori informazioni, vedi Utilizzo dei dati persistenti in Verse.
Questa pagina illustra alcune buone prassi quando si utilizzano dati persistenti in Verse.
Utilizzo delle classi per aggiungere nuovi campi successivamente
Al momento, l'unico tipo di dati persistenti che puoi modificare dopo la pubblicazione della tua isola è il tipo class a condizione che i nuovi campi abbiano valori predefiniti. Ciò significa che il caricamento dei dati salvati da una versione precedente includerà quindi i nuovi campi e i loro valori predefiniti.
Vediamo un esempio of pubblicazione di un progetto con i seguenti dati persistenti.
player_profile_data := class<final><persistable>:
Class:player_class = player_class.Villager
XP:int = 0
Rank:int = 0Dato che il progetto è pubblicato e in tempo reale, i giocatori che hanno giocato avranno questi dati persistenti associati. Se aggiungessimo altri campi ai dati del profilo dei giocatori, per esempio il numero e lo storico delle missioni, i dati persistenti apparirebbero in questo modo nel progetto aggiornato.
player_profile_data := class<final><persistable>:
Class:player_class = player_class.Villager
XP:int = 0
Rank:int = 0
CompletedQuestCount:int = 0
QuestHistory:[]string = array{}I dati persistenti dei giocatori che hanno giocato con la prima versione della classe player_profile_data includeranno i nuovi campi:
CompletedQuestCountcon il valore0che è il valore predefinito specificato.QuestHistorycon un array di stringhe vuoto, che è il valore predefinito indicato.
Funziona perché è stato inserito un valore predefinito per i nuovi campi per aggiornare la versione precedente dei dati.
Dato che solo le classi possono essere aggiornate dopo che un progetto viene pubblicato, consigliamo caldamente di utilizzare una classe come tipo di valore di ogni variabile con ambito di modulo weak_map.
For maggiori dettagli su come creare una classe persistente, vedi Tipi persistenti.
Utilizzare i costruttori per gli aggiornamenti parziali
Se utilizzi le classi, consigliamo di utilizzare un costruttore per creare una nuova istanza della tua classe che contiene lo stato aggiornato, perché i costruttori ti permettono di eseguire aggiornamenti parziali delle classi.
L'esempio seguente mostra come aggiornare PlayerProfileDataMap. La funzione GrantXP() fornisce i dati attuali del giocatore indicato e poi richiama il costruttore MakePlayerProfileData() per creare una nuova versione dei dati del profilo. Dato che i dati di origine del giocatore vengono passati al costruttore insieme al nuovo valore di PE, verrà aggiornato solo il valore di PE mentre tutti gli altri dati del giocatore non vengono modificati.
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:
L'esempio precedente mostra come aggiornare un campo; se vuoi aggiornarne più di uno, puoi usare:
set PlayerProfileDataMap[Player] = player_profile_data:
QuestHistory := UpdatedSaveData.QuestHistory
CompletedQuestCount := OldData.CompletedQuestCount + 1
MakePlayerProfileData<constructor>(OldData)Assegnazione della versione ai dati persistenti
Ti consigliamo di utilizzare il controllo delle versioni nelle classi persistenti per rilevare la versione dell'istanza per i dati salvati in precedenza per un giocatore. Utilizzando le versioni, puoi rilevare e applicare le migrazioni se la tua definizione di classe persistente o logica di gameplay cambia con il passare del tempo.
Sebbene sia possibile utilizzare valori interi o stringa per denotare la versione della classe persistente, consigliamo di utilizzare i valori opzione per memorizzare i riferimenti alle versioni attuali e passate dei dati. Considera la configurazione seguente:
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.
In questo caso, la classe player_data contiene valori opzione sia per la prima che per la seconda versione della classe di dati associata, che sono rappresentate dalle classi v1_player_data e v2_player_data. Deve essere impostata una sola delle versioni V1 o V2 per evitare che i giocatori abbiano più versioni di dati associate.
I dati del giocatore V1 originali contengono tre campi int. La versione V2 dei dati modifica il campo Playtime in un float e aggiunge due nuovi campi. Poiché il tipo di campo Playtime è cambiato nella versione V2, dovrà essere convertito per tutti i giocatori che hanno ancora i vecchi dati V1. Quando un giocatore con i vecchi dati V1 entra in un'esperienza, puoi utilizzare le funzioni del costruttore ausiliario per compilare una nuova classe di dati V2 basata sui vecchi dati in questo modo:
# 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
Possono presentarsi situazioni in cui vuoi forzare una reimpostazione dei dati dei giocatori che entrano nella tua isola. Puoi farlo riassegnando un valore predefinito per i dati persistenti nella 'weak_map' per tutti i giocatori e modificando il campo Version della classe. Se utilizzi dati con versione opzionale, puoi reimpostare i dati impostando i campi opzionali su false.
Per sapere se i dati del giocatore sono già stati reimpostati, puoi controllare il valore della Version nei dati persistenti del giocatore per controllare se è il più recente.
Verificare che i dati persistenti siano all'interno dei limiti
Se il tuo aggiornamento può influenzare la dimensione totale dei tuoi dati persistenti, devi verificare che i dati persistenti siano ancora all'interno dei vincoli di sistema di persistenza di Verse. Se cerchi di aggiornare i dati persistenti e viene superato il limite di dimensioni, otterrai un errore di runtime di Verse. Per maggiori dettagli, consulta Massima dimensione degli oggetti persistenti.
Puoi controllare il modo in cui i tuoi aggiornamenti influenzano la dimensione totale utilizzando la funzione FitsInPlayerMap().
Nell'esempio seguente, i dati persistenti contengono un array di stringhe. Se l'array diventa troppo grande per essere archiviato in weak_map che si verifica quando FitsInPlayerMap() non riesce, l'esempio svuota l'array e aggiunge solo l'elemento salvato più recente.
# 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]
Reagire all'entrata di un giocatore nella tua isola
Quando un nuovo giocatore entra nella tua isola, non vengono aggiunti automaticamente valori alla weak_map persistente. Devi aggiungere il valore in Verse.
Per farlo, puoi controllare se un giocatore si trova già nella weak_map ovunque tu acceda o puoi aggiungere alla weak_map i dati predefiniti ogni volta che entra un giocatore e puoi ricevere un avviso mediante la sottoscrizione all'evento di gioco PlayerAddedEvent().
GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)
# Later in your file
OnPlayerAdded(Player:player):void=
if:
not PlayerProfileDataMap[Player]
set PlayerProfileDataMap[Player] = player_profile_data{}