persistence doesnt work eventho their are no errors

hello can somebody look at my code and tell me why the persistence isnt working? or even fix it for me :slight_smile:
Game_Manager:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Colors/NamedColors }

#This Code is a Game/Player Manager for a Tycoon Game Mode

Custom_Player := class<unique>():       #custom player class that holds the players values
    Player : player

    var MyUI : canvas = canvas{}
    var MoneyAmount : float = 0.0
    var IdleMoneyAmount : float = 0.0
    var ScrapAmount : float = 0.0
    var ComponentsAmount : float = 0.0
    var CurrentBoost : float = 1.0
    var CurrencyTB : text_block = text_block{}
    

    InitiateUI(): void=       #Initalizes and adds the players UI
        if(PlayerObj := Player, PlayerUI := GetPlayerUI[PlayerObj]):
            set MyUI = CreateMyUI()
            PlayerUI.AddWidget(MyUI)

            
    UpdateUI(): void=        #Updates the players UI to new values
        if(PlayerObj := Player, PlayerUI := GetPlayerUI[PlayerObj]):
            PlayerUI.RemoveWidget(MyUI)
            set MyUI = CreateMyUI()
            PlayerUI.AddWidget(MyUI)

    
    Collect(Amount : float, ResourceType: string): void=   #Increases a players resource amount by a specific value
        if( ResourceType = "Money"):
            set MoneyAmount += Amount

        else if(ResourceType = "IdleMoney"):
            set IdleMoneyAmount += Amount

        else if(ResourceType = "Scrap"):
            set ScrapAmount += Amount

        else if(ResourceType = "Components"):
            set ComponentsAmount += Amount
    
        else:
            Print("Invalid Resource Name")

        UpdateUI()


    Spend(Amount: float, ResourceType: string): logic= # Sees if player has enough of a resource to spend and removes it if they do
        if(ResourceType = "Money", MoneyAmount >= Amount):
            set MoneyAmount -= Amount

        else if(ResourceType = "IdleMoney", IdleMoneyAmount >= Amount):
            set IdleMoneyAmount -= Amount

        else if(ResourceType = "Scrap", ScrapAmount >= Amount):
            set ScrapAmount -= Amount

        else if(ResourceType = "Components", ComponentsAmount >= Amount):
            set ComponentsAmount -= Amount

        else:
            Print("Not Enough Money")
            return false

        UpdateUI()
        return true

    Boost(BoostAmount : float) : void=     #Function Used to Increase a Players Boost Amount
        set CurrentBoost += BoostAmount
        UpdateUI()

    RemoveBoost(BoostAmount : float) : void=    #Function Used to Decrease a Players Boost Amount
        set CurrentBoost -= BoostAmount
        UpdateUI()


    CreateMyUI() : canvas =   #Creates the Main Hud UI
        NewIdleMoneyAmount := IdleMoneyAmount * CurrentBoost
        
        MyCanvas: canvas = canvas:
            Slots := array:
                canvas_slot:   #Idle Money Resource Text
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := 105.0, Top := 0.0, Right := 170.0, Bottom := 45.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := text_block:
                        DefaultTextColor := White
                        DefaultShadowOffset := option{vector2{X:=1.0,Y:=1.0}}
                        DefaultShadowColor := Black
                        DefaultText := NewMessageSec(IdleMoneyAmount) 

                canvas_slot:    #Money Resource Text
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := 105.0, Top := 90.0, Right := 700.0, Bottom := 45.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := text_block:
                        DefaultTextColor := White
                        DefaultShadowOffset := option{vector2{X:=1.0,Y:=1.0}}
                        DefaultShadowColor := Black
                        DefaultText := NewMessage(MoneyAmount)

                canvas_slot:    #Scrap Text
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := 105.0, Top := 180.0, Right := 700.0, Bottom := 45.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := text_block:
                        DefaultTextColor := White
                        DefaultShadowOffset := option{vector2{X:=1.0,Y:=1.0}}
                        DefaultShadowColor := Black
                        DefaultText := NewMessage(ScrapAmount)

                canvas_slot:    #Components Text
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := 105.0, Top := 270.0, Right := 700.0, Bottom := 45.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := text_block:
                        DefaultTextColor := White
                        DefaultShadowOffset := option{vector2{X:=1.0,Y:=1.0}}
                        DefaultShadowColor := Black
                        DefaultText := NewMessage(ComponentsAmount)
                        
                        
               
                canvas_slot:  #Idle Money Resource Image
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := -65.0, Top := 0.0, Right := 150.0, Bottom := 150.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := texture_block:
                        DefaultImage := SulfurOre_Icon

                canvas_slot:   #Money Resource Image
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := -65.0, Top := 90.0, Right := 150.0, Bottom := 150.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := texture_block:
                        DefaultImage := Sulfur_icon1

                canvas_slot:  #Resource2 Image
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := -65.0, Top := 180.0, Right := 445.0, Bottom := 250.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := texture_block:
                        DefaultImage := ScrapIcon1

                canvas_slot:  #Resource3 Image
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := -65.0, Top := 270.0, Right := 445.0, Bottom := 250.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := texture_block:
                        DefaultImage := ComponentsIcon1
                canvas_slot:   
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
                    Offsets := margin{Left := 105.0, Top := 0.0, Right := 120.0, Bottom := 45.0}
                    Alignment := vector2{X := 0.0, Y := 0.5}
                    SizeToContent := false
                    Widget := CurrencyTB



    NewMessage (value : float) : message =   #Rounds values for resources
        #Round if over 100k
        var newesstvalue : float = 0.0
        if(value > 100000.0 and value < 1000000.0):
            newvalue := ((value/1000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageThou(newesstvalue)

        #Round if over 1M
        else if(value > 1000000.0 and value < 1000000000.0):
            newvalue := ((value/1000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageMil(newesstvalue)


        #Round if over 1B 
        else if(value > 1000000000.0 and value < 1000000000000.0):
            newvalue := ((value/1000000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageBil(newesstvalue)

        #Round if over 1T 
        else if(value > 1000000000000.0):
            newvalue := ((value/1000000000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageTril(newvalue)

        #Returns normal value if anything else
        else:
            return StringToMessage(value)


    NewMessageSec(value : float) : message=         #Rounds Values but for IdleMoney Instead
        var newesstvalue : float = 0.0

        #Round if over 100k
        if(value > 100000.0 and value < 1000000.0):
            newvalue := ((value/1000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageSecThou(newesstvalue)

        #Round if over 1M
        else if(value > 1000000.0 and value < 1000000000.0):
             newvalue := ((value/1000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageSecMil(newesstvalue)

        #Round if over 1B 
        else if(value > 1000000000.0 and value < 1000000000000.0):
            newvalue := ((value/1000000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageSecBil(newesstvalue)

        #Round if over 1T 
        else if(value > 1000000000000.0):
            newvalue := ((value/1000000000000.0) * 10.0)
            if(roundvalue := (Round[newvalue]* 0.1)):
                set newesstvalue = roundvalue
            return StringToMessageSecTril(newesstvalue)

        #Returns normal value if anything else
        else:
            return StringToMessageSec(value)


    #Message Converters For Resources
    RealStringToMessage<localizes>(value:string) : message = "{value}"
    StringToMessage<localizes>(value:float) : message = "{value}"
    StringToMessageThou<localizes>(value:float) : message = "{value}K"
    StringToMessageMil<localizes>(value:float) : message = "{value}M"
    StringToMessageBil<localizes>(value:float) : message = "{value}B"
    StringToMessageTril<localizes>(value:float) : message = "{value}T"


    #Message Converters for Idle Values
    StringToMessageSec<localizes>(value:float) : message = "{value} / Sec"
    StringToMessageSecThou<localizes>(value:float) : message = "{value}K / Sec"
    StringToMessageSecMil<localizes>(value:float) : message = "{value}M / Sec"
    StringToMessageSecBil<localizes>(value:float) : message = "{value}B / Sec"
    StringToMessageSecTril<localizes>(value:float) : message = "{value}T / Sec"

Game_Manager := class(creative_device):
    @editable PlayerSpawners : []player_spawner_device = array{}
    @editable BaseClassSelector : class_and_team_selector_device = class_and_team_selector_device{}


    var PlayersMap : [player]Custom_Player = map{}
    PersistenceManager : Persistence_Manager = Persistence_Manager{}
    
    OnBegin<override>()<suspends>:void=
        for(Spawner : PlayerSpawners):     
            Spawner.SpawnedEvent.Subscribe(InitiatePlayer)  #Activates when a player is spawned on a spawn pad 

        for(Player : GetPlayspace().GetPlayers()){InitiatePlayer(Player)}
            GetPlayspace().PlayerAddedEvent().Subscribe(InitiatePlayer)

    InitiatePlayer(Agent:agent): void=   #Initiates the player into the playermap
        if(Player := player[Agent], FC:= Agent.GetFortCharacter[]):
            PersistenceManager.InitializePlayer(Player)
            if(PlayerExists := PlayersMap[Player]):
            else:
                BaseClassSelector.ChangeTeam(Agent)   #Changes to a base class
                SavedPlayerStats := PersistenceManager.GetPlayerStats(Player)
                    if(set PlayersMap[Player] = Custom_Player{       
                        Player := Player
                        MoneyAmount := SavedPlayerStats.Money
                        }){}
                        if(CP := PlayersMap[Player]):
                            CP.InitiateUI()
    stringToMessage<localizes>(String : string) : message = "{String}"
   


Persistence_Manager:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

player_stats_table := class<final><persistable>:

    Money : float = 0.0
                      
var PlayerStatsMap : weak_map(player , player_stats_table) = map{}
                        
MakePlayerStatsTable<constructor>(OldTable : player_stats_table)<transacts> := player_stats_table:
    Money := OldTable.Money
                        
                        
Persistence_Manager := class():
                        
    InitializePlayer(Player : player) : void=
        if:
            Player.IsActive[]
            not PlayerStatsMap[Player]
            set PlayerStatsMap[Player] = player_stats_table{}
                        
                        
    GetPlayerStats(Agent:agent) : player_stats_table=
        var NewPlayerStats : player_stats_table = player_stats_table{}
        if:
            Player := player[Agent]
            PlayerTable := PlayerStatsMap[Player]
            set NewPlayerStats = PlayerTable
        return NewPlayerStats
                        
    UpdatePlayerStats(Agent : agent, Amount : float, Stat : string) : void=
        if:
            Player := player[Agent]
            Player.IsActive[]
            PlayerTable := PlayerStatsMap[Player]
            if(Stat = "MoneyAmount"):
                set PlayerStatsMap[Player] = player_stats_table:
                    MakePlayerStatsTable<constructor>(PlayerTable)
                    Money := Amount

since im new to coding i used a tutorial for the codes, i would like to understand why it isnt working, Thanks for reading
Francis

This a lot of code to go through and debug, did you follow this tutorial? This is what works for me: https://dev.epicgames.com/documentation/en-us/uefn/using-persistable-data-in-verse#required-weak-map-with-class-type

Persistent data is one of the hardest aspects of Verse coding so I recommend being very comfortable with the language before you use it, otherwise many problems will occur. A better way to store persistent data if you are only storing something like money is to use stat creator devices, then you don’t have to code the persistence stuff yourself.