databaserobloxluau

Roblox Database doesn't save player's data


local DataStoreService = game:GetService("DataStoreService")
local DataBase = DataStoreService:GetDataStore("data")
local sessionData = {}
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
    Player.CharacterAdded:Connect(function(Character)
        Character.Humanoid.JumpHeight = 275
    end)

    local leaderstats = Instance.new("Folder", Player)
    leaderstats.Name = "leaderstats"
    
    local FolderOfValues = Instance.new("Folder",leaderstats)
    FolderOfValues.Name = "FolderOfValues"

    local Coins = Instance.new("IntValue", FolderOfValues)
    Coins.Name = "Coins"

    local Gravity = Instance.new("IntValue", FolderOfValues)

    Gravity.Name = "Gravity"


    local success = nil
    local PlayerData = nil
    local attempt = 1

    repeat
        success, PlayerData = pcall(function()
            return DataBase:GetAsync(Player.UserId, sessionData[Player.UserId])
        end)

        attempt += 1
        if not success then

            warn(PlayerData)
            task.wait(2)

        end
    until success or attempt == 5
    
    if success then
        print("Players data connected")
        if not PlayerData then
            print("Assigning default data")
            PlayerData = {
                ["Coins"] = 0,
                ["Gravity"] = 10
            }
        end
        sessionData[Player.UserId] = PlayerData
    else
        warn("Unable to get data for the player")
        Player:Kick("Unable to load your data, try again next time")
    end
    workspace.Gravity = Gravity.Value



    Coins.Value = sessionData[Player.UserId].Coins
    Coins.Changed:Connect(function()
        sessionData[Player.UserId].Coins = Coins.Value
    end)


    Gravity.Value = sessionData[Player.UserId].Gravity
    Gravity.Changed:Connect(function()
        sessionData[Player.UserId].Gravity = Gravity.Value
    end)

end)


function PlayerLeaving(Player)
    if sessionData[Player.UserId] then
        local success = nil
        local errormsg = nil
        local attempt = 1

        repeat
            success, errormsg = pcall(function()
                DataBase:SetAsync(Player.UserId, sessionData[Player.UserId])

            end)
            attempt += 1
            if not success then
                warn(errormsg)
                task.wait(3)

            end


        until success or attempt == 5

        if success then
            print("Data saved")
        else
            warn("Not saved")
        end


    end
end

game.Players.PlayerRemoving:Connect(PlayerLeaving)


function ServerShutDown()
    print("Server Shutting down")
    RunService:IsStudio(function()
        return
    end)
    for i, Player in ipairs(game.Players:GetChildren()) do
        task.spawn(function()
            PlayerLeaving(Player)
        end)
    end
end

game:BindToClose(ServerShutDown)

when i enter the game with no data, it prints "Player's data connected" even though i had no progress. When i leave with progress, nothing prints suggesting my data has not been saved. after i join, nothing is there. I've read through 10 different posts and none of them have helped. Please someone help!


Solution

  • Assuming you are in studio, did you enable API access for studio place testing? If not, you won't have access to the datastore used by the actual published game.

    As I read our script, I recognized that you used GetAsync with two arguments, while there is only one argument. This will most likely not cause a problem the first time the player joins, as it will return nil, but the second time a player joins, because it at that point is populated, could cause random unwanted behavior.

    I suggest you also assign the user id of the player to a local variable, as while the script is still running, the player would be dereferenced and instead return nil, most likely causing your issue.

    Edit After replicated your code myself, I found that it succesfully saved and everything. To explain your confusion about success being true, as long as it does not error, it will be successful. Meaning that the request went through without problems and returned the data, which is nil if none is present.

    I'm unsure why you're confused about this as you've added the conditional clause to check if PlayerData is present or not.

    It also saves successfully and upon rejoining gives the same data. Image of data being present in datastore

    Your actual problem is that you're pressing the Stop button, which doesn't wait until server shutdown event listeners have completed their work.