Persistence to save gold and diamonds across sessions

Hello everyone,
I have been having issues getting my map to save the players gold and diamonds collected to the next session. I do have a save point that works, but I am looking for one that does it automatically throughout gameplay. I am new to Verse and have tried a few samples i found online but none of them have worked. As soon as i end the game and come back, its all gone. I am using granters for the gold and diamonds attached to other devices, such as a granter that gives one diamond when you eliminate an NPC and gold that gives 5 gold when a silver collectible coin in collected. Any help on how i can do this would be greatly appreciated. I know you all can probably do this in your sleep lol

Hey @Rolin_Eos ! How are you?

I really like this question! I’ve been researching about this and I highly recomend you to watch this playlist on youtube: https://www.youtube.com/watch?v=gjJJBKTduBs&list=PLqeAABnX85Z_ZoZcVxUhg1CvPw4qf22fH&index=1

It explains really well how to create persistent values, which you will need to do what you are trying.

You should implement all the things the first video shows and, after that you will be able to add some logic to add the items to the players on spawn!

Of course you will need to change some things (read this AFTER watching and implementing the code from the video!)

  1. Your persistable class and constructor will have your variables Gold and Diamonds instead of the ones in the video

  2. Instead of subscribing to a button device, you will subscribe to your Item Granters

    # Actualitem granters
    @editable
    var GoldGranter : item_granter_device = item_granter_device{}
    
    @editable
    var DiamondGranter : item_granter_device = item_granter_device{}

    # Aux item granters
    @editable
    var AuxGoldGranter : item_granter_device = item_granter_device{}
    
    @editable
    var AuxDiamondGranter : item_granter_device = item_granter_device{}

    OnBegin<override>()<suspends>:void =
        # Subscribe to item granters
        GoldGranter.ItemGrantedEvent.Subscribe(OnGoldGranted)
        DiamondGranter.ItemGrantedEvent.Subscribe(OnDiamondGranted)
        
        # Inicializar datos para jugadores que ya están en el juego
        Players := GetPlayspace().GetPlayers()
        for (Player : Players):
            InitializePlayerData(Player)
  1. These will be your functions for the item granters
    # Function executed when Gold is granted
    OnGoldGranted(Agent : agent):void =
        # Convert the agent to player
        if(Player:=player[Agent]):
            SD:=Player.GetSaveData()
            NewSD:=save_data:
                # Copy the values you don't change
                MakeSaveData<constructor>(SD)
                # Values you are changing
                Gold:=SD.Gold+1 # Increment Gold by 1
            Player.SetSaveData(NewSD)
    
    # Function executed when a Diamond is granted
    OnDiamondGranted(Agent : agent):void =
        # Convert the agent to player
        if(Player:=player[Agent]):
            SD:=Player.GetSaveData()
            NewSD:=save_data:
                # Copy the values you don't change
                MakeSaveData<constructor>(SD)
                # Values you are changing
                Diamonds:=SD.Diamonds+1 # Increment Diamonds by 1
            Player.SetSaveData(NewSD)

The things you will need to do after implementing that code are the following:

  1. Add 2 Auxiliary Item Granters for Gold and Diamonds
    # Aux item granters
    @editable
    var AuxGoldGranter : item_granter_device = item_granter_device{}
    
    @editable
    var AuxDiamondGranter : item_granter_device = item_granter_device{}
  1. create this new function:
    # Initialize Player's data
    InitializePlayerData(Player : player):void =
        SD:=Player.GetSaveData()
        Gold := SD.Gold
        Diamonds := SD.Diamonds
        for (i := 0..Gold):
            AuxGoldGranter.GrantItem(Player)
            Print("{i}")
        for (i := 0..Diamonds):
            AuxDiamondGranter.GrantItem(Player)
            Print("{i}")
  1. Create this other function as well
    # Initialize new players that join the session later
    OnPlayerAdded(Player : player):void =
        InitializePlayerData(Player)
  1. Call those functions this way into you “OnBegin”
        # Initialize data for current players
        Players := GetPlayspace().GetPlayers()
        for (Player : Players):
            InitializePlayerData(Player)
        
        # Subscribe to new players joining the game
        GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)

Remember to add

And that’s it! With this, you should be able to store the amount of items for each player and then grant those items back to the corresponding player when it login to your island!

Hope this helps you!