Search code examples
scriptingroblox

How do I make a save system for a leader board with more than 3 stats


I want to make a save system so that people don't have to restart every single time they play

I don't really know what to do so I will show you the code for my leader stats this is located in the work space

local function onPlayerJoin(player)
    local leaderstats = Instance.new("Model")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player


    local gold = Instance.new("IntValue")
    gold.Name = "JumpBoost"
    gold.Value = 150
    gold.Parent = leaderstats

        local speed = Instance.new("IntValue")
    speed.Name = "Speed"
    speed.Value = 20
    speed.Parent = leaderstats

    local coin = Instance.new("IntValue")
    coin.Name = "CloudCoins"
    coin.Value = 0
    coin.Parent = leaderstats

    local rebirths = Instance.new("IntValue")
    rebirths.Name = "Rebirths"
    rebirths.Value = 0
    rebirths.Parent = leaderstats

end


game.Players.PlayerAdded:Connect(onPlayerJoin)

Again I don't really know what to do so, please help.


Solution

  • The documentation for Data Stores is pretty good. An important warning for testing :

    DataStoreService cannot be used in Studio if a game is not configured to allow access to API services.

    So you will have to publish the game and configure it online to allow you to make HTTP requests and access the Data Store APIs. So be sure to look at the section in that link titled, Using Data Stores in Studio, it will walk you through the menus.

    Anyways, right now, you are creating the player's starting values when they join the game. DataStores allow you save the values from the last session and then load those in the next time they join.

    Roblox DataStores allow you to store key-value tables. Let's make a helper object for managing the loading and saving of data.

    Make a ModuleScript called PlayerDataStore :

     -- Make a database called PlayerExperience, we will store all of our data here
    local DataStoreService = game:GetService("DataStoreService")
    local playerStore = DataStoreService:GetDataStore("PlayerExperience")
    
    local PlayerDataStore = {}
    
    function PlayerDataStore.getDataForPlayer(player, defaultData)
        -- attempt to get the data for a player
        local playerData
        local success, err = pcall(function()
            playerData = playerStore:GetAsync(player.UserId)
        end)
    
        -- if it fails, there are two possibilities:
        --  a) the player has never played before
        --  b) the network request failed for some reason
        -- either way, give them the default data
        if not success or not playerData then
            print("Failed to fetch data for ", player.Name, " with error ", err)
            playerData = defaultData
        else
            print("Found data : ", playerData)
        end
    
        -- give the data back to the caller
        return playerData
    end
    
    function PlayerDataStore.saveDataForPlayer(player, saveData)
        -- since this call is asyncronous, it's possible that it could fail, so pcall it
        local success, err = pcall(function()
            -- use the player's UserId as the key to store data
            playerStore:SetAsync(player.UserId, saveData)
        end)
        if not success then
           print("Something went wrong, losing player data...")
           print(err)
        end
    end
    
    
    return PlayerDataStore
    

    Now we can use this module to handle all of our loading and saving.

    At the end of the day, your player join code will look very similar to your example, it will just try to first load the data. It is also important to listen for when the player leaves, so you can save their data for next time.

    In a Script next to PlayerDataStore :

    -- load in the PlayerDataStore module
    local playerDataStore = require(script.Parent.PlayerDataStore)
    
    
    local function onPlayerJoin(player)
        -- get the player's information from the data store,
        --  and use it to initialize the leaderstats
        local defaultData = {
            gold = 150,
            speed = 0,
            coins = 0,
            rebirths = 0,
        }
        local loadedData = playerDataStore.getDataForPlayer(player, defaultData)
    
        -- make the leaderboard
        local leaderstats = Instance.new("Model")
        leaderstats.Name = "leaderstats"
        leaderstats.Parent = player
    
        local gold = Instance.new("IntValue")
        gold.Name = "JumpBoost"
        gold.Value = loadedData.gold
        gold.Parent = leaderstats
    
        local speed = Instance.new("IntValue")
        speed.Name = "Speed"
        speed.Value = loadedData.speed
        speed.Parent = leaderstats
    
        local coin = Instance.new("IntValue")
        coin.Name = "CloudCoins"
        coin.Value = loadedData.coins
        coin.Parent = leaderstats
    
        local rebirths = Instance.new("IntValue")
        rebirths.Name = "Rebirths"
        rebirths.Value = loadedData.rebirths
        rebirths.Parent = leaderstats
    end
    
    local function onPlayerExit(player)
        -- when a player leaves, save their data
        local playerStats = player:FindFirstChild("leaderstats")
        local saveData = {
            gold = playerStats.JumpBoost.Value,
            speed = playerStats.Speed.Value,
            coins = playerStats.CloudCoins.Value,
            rebirths = playerStats.Rebirths.Value,
        }
        playerDataStore.saveDataForPlayer(player, saveData)
    end
    
    
    game.Players.PlayerAdded:Connect(onPlayerJoin)
    game.Players.PlayerRemoving:Connect(onPlayerExit)
    

    Hope this helps!