Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

Save/load data stopped working?

Asked by
Lagfss 36
2 years ago

Randomly when I was trying to encode boats into my game I realize that whenever I would go in to test the buying system my money would always be set back to whatever it was. There are no errors when saving/loading as It prints the message it should when it is successful

local remote = game:GetService("ReplicatedStorage"):WaitForChild("QuestRemote")

local data = game:GetService("DataStoreService")
local my_data = data:GetDataStore("my_data")

game.Players.PlayerAdded:Connect(function(player)
    --for stats
    local gold
    local level
    local exp

    -- for quest stuff
    local QuestTitle
    local QuestTask
    local QuestObjective
    local QuestProgress
    local QuestGold
    local QuestExp

    --to tell if the boat is bought or not
    local schooner_ship


    local sucess, errormessage = pcall(function()
        gold = my_data:GetAsync(player.UserId.."-gold")
        level = my_data:GetAsync(player.UserId.."-level")
        exp = my_data:GetAsync(player.UserId.."-exp")

        QuestTitle = my_data:GetAsync(player.UserId.."-QuestTitle")
        QuestTask = my_data:GetAsync(player.UserId.."-QuestTask")
        QuestObjective = my_data:GetAsync(player.UserId.."-QuestObjective")
        QuestProgress = my_data:GetAsync(player.UserId.."-QuestProgress")
        QuestGold = my_data:GetAsync(player.UserId.."-QuestGold")
        QuestExp = my_data:GetAsync(player.UserId.."-QuestExp")

        schooner_ship = my_data:GetAsync(player.UserId.."-schooner_ship")

    end)

    if sucess then
        print("data sucessfully loaded")
        player.stats.Gold.Value = gold
        player.stats.Level.Value = level
        player.stats.Exp.Value = exp

        player.QuestInformation.QuestTitle.Value = QuestTitle
        player.QuestInformation.QuestTask.Value = QuestTask
        player.QuestInformation.QuestObjective.Value = QuestObjective
        player.QuestInformation.QuestProgress.Value = QuestProgress
        player.QuestInformation.QuestGold.Value = QuestGold
        player.QuestInformation.QuestExp.Value = QuestExp

        player.Boats_bought.schooner_ship.Value = schooner_ship

        if QuestTitle == "Default" then
            --does nothing if the title is default
        else
            remote:FireClient(player, "TransferBritish")
        end
    else
        print("there was an error getting your data")
        warn(errormessage)
    end

end)

game.Players.PlayerRemoving:Connect(function(player)

    --for all stats
    local sucess, errormessage = pcall(function()
        my_data:SetAsync(player.UserId.."-gold", player.stats.Gold.Value)
        my_data:SetAsync(player.UserId.."-level", player.stats.Level.Value)
        my_data:SetAsync(player.UserId.."-exp", player.stats.Exp.Value)
        -- for quest progression
        my_data:SetAsync(player.UserId.."-QuestTitle", player.QuestInformation.QuestTitle.Value)
        my_data:SetAsync(player.UserId.."-QuestTask", player.QuestInformation.QuestTask.Value)
        my_data:SetAsync(player.UserId.."-QuestObjective", player.QuestInformation.QuestObjective.Value)
        my_data:SetAsync(player.UserId.."-QuestProgress", player.QuestInformation.QuestProgress.Value)
        my_data:SetAsync(player.UserId.."-QuestGold", player.QuestInformation.QuestGold.Value)
        my_data:SetAsync(player.UserId.."-QuestExp", player.QuestInformation.QuestExp.Value)

        my_data:SetAsync(player.UserId.."-schooner_ship", player.Boats_bought.schooner_ship.Value)
    end)

    if sucess  then
        print("data successfully saved!")
    else
        print("there was an error saving data")
        warn(errormessage)
    end

end)

I did go into server-side while coding to give myself money so maybe that could be the issue but I've never had a problem like that previously

1
You didn’t make the stats dolder in the player. Make the stats folder in PlayerAdded T3_MasterGamer 2189 — 2y

1 answer

Log in to vote
1
Answered by 2 years ago
Edited 2 years ago

I noticed that you didn't make the stats folder in the player. In PlayerAdded, always make the stats folder, then you can identify it. Also, when getting ad saving the data, I recommend repeating the pcall until it returns success and putting all data in a table when saving it.

And when the server is getting shut down, it kicks the player before it fires the PlayerRemoving event. To avoid that, we'll use the game:BindToClose() function.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")

local remote =ReplicatedStorage:WaitForChild("QuestRemote")
local my_data = DataStoreService:GetDataStore("my_data")

function GetData(player)
    -- getting the data
    local key = player.UserId .. "-player_dataTable"
    local success, dataTable

    repeat
        success, dataTable = pcall(my_data.GetAsync, my_data, key)
    until (success and dataTable) or not Players:FIndFirstChild(player.Name)

    if success then
        -- for stats
        player.stats.Gold.Value = dataTable.stats.Gold or 0
        player.stats.Level.Value = dataTable.stats.Level or 0
        player.stats.Exp.Value = dataTable.stats.Exp or 0

        -for quest stuff
        player.QuestInformation.QuestTitle.Value = dataTable.questInfo.QuestTitle or ""
        player.QuestInformation.QuestTask.Value = dataTable.questInfo.QuestTask or ""
        player.QuestInformation.QuestObjective.Value = dataTable.questInfo.QuestObjective or ""
        player.QuestInformation.QuestProgress.Value = dataTable.questInfo.QuestProgress or 0
        player.QuestInformation.QuestGold.Value = dataTable.questInfo.QuestGold or 0
        player.QuestInformation.QuestExp.Value = dataTable.questInfo.QuestExp or 0

        -- others
        player.Boats_bought.schooner_ship.Value = dataTable.boatsBought.schooner_ship or false

        print("Data has been loaded successfully!")
    end
end

function SaveData(player)
    local stats = player:WaitForChild("stats")
    local questInfo = player:WaitForChild("QuestInformation")
    local boatsBought = player:WaitForChild("Boats_bought")

    -- saving the data
    local key = player.UserId .. "-player_dataTable"
    local dataTable = {
        ["stats"] = {
            Gold = stats:WaitForChild("Gold").Value,
            Level = stats:WaitForChild("Level").Value,
            Exp = stats:WaitForChild("Exp").Value
        },

        ["questInfo"] = {
            QuestTitle = questInfo:WaitForChild("QuestTitle").Value,
            QuestTask = questInfo:WaitForChild("QuestTask").Value,
            QuestObjective = questInfo:WaitForChild("QuestObjective").Value,
            QuestProgress = questInfo:WaitForChild("QuestProgress").Value,
            QuestGold = questInfo:WaitForChild("QuestGold").Value,
            QuestExp = questInfo:WaitForChild("QuestExp").Value
        },

        ["boatsBought"] = {
            schooner_ship = boatsBought:WaitForChild("schooner_ship").Value
        }
    }

    local success, result

    repeat
        success, result = pcall(my_data.UpdateAsync, my_data, key, function(oldData)
            return dataTable
        end)
    until success

    if success then
        print("Data has been saved successfully!")
    end
end

for _, player in ipairs(Players:GetPlayers()) do
    coroutine.wrap(GetData)(player)
end

Players.PlayerAdded:Connect(GetData)
Players.PlayerRemoving:Connect(SaveData)

game:BindToClose(function()
    if RunService:IsStudio() then
        task.wait(2)
    else
        local finished = Instance.new("BindableEvent")
        local allPlayers = Players:GetPlayers()
        local leftPlayers = #allPlayers

        for _, player in ipairs(allPlayers) do
            coroutine.wrap(function()
                SaveData(player)
                leftPlayers -= 1
                if leftPlayers == 0 then
                    finished:Fire()
                end
            end)()
        end

        finished.Event:Wait()
    end
end)
0
Thanks for the reply!. The player stats folder and values are already created and assigned to the player it's just in a separate script not related to this one. Also correct me if i'm wrong but bindtoclose is a function for when the server shuts down?. The script above is just for saving a players data when they decide to leave the game Lagfss 36 — 2y
0
Also the script above has worked just fine for the longest time and I haven't touched it up until recently when I did a boat buying system and noticed then that the new data was not saving. It only saves the old data even though in the player folder the value is updated? Lagfss 36 — 2y
0
If that's the case, use SetAsync instead. When the server shuts down, it's not always that the PlayerRemoving event will run.I fixed the script. T3_MasterGamer 2189 — 2y
0
Oh wait nvm you still have to use UpdateAsync T3_MasterGamer 2189 — 2y
Ad

Answer this question