What do you want to achieve?
I made this DataStore Script for stats in my game and it will not save the progress of the stats.
What is the issue? Include screenshots / videos if possible!
I’m not quite sure since there are no errors in output. I’ve looked throughout the script multiple times and see no problem with it.
What solutions have you tried so far?
I’ve tired making new simple DataStore Scripts which still do not working. looked throughout YouTube for what could be wrong and even DevFourm and still no hope.
HERE IS HE CODE
local DataStore = game:GetService("DataStoreService"):GetDataStore("Focus_Wisdom_GoodFaith_BadFaith_1")
local function SaveData(Player)
local SaveTable = {}
for i = 1, #Player:WaitForChild("StatsData"):GetChildren() do
if i == 1 then
SaveTable[1] = Player:WaitForChild("StatsData"):WaitForChild("Focus").Value
elseif i == 2 then
SaveTable[2] = Player:WaitForChild("StatsData"):WaitForChild("Wisdom").Value
elseif i == 3 then
SaveTable[3] = Player:WaitForChild("StatsData"):WaitForChild("GoodFaith").Value
elseif i == 4 then
SaveTable[4] = Player:WaitForChild("StatsData"):WaitForChild("BadFaith").Value
end
DataStore:SetAsync(Player.UserId, SaveTable)
end
end
game.Players.PlayerAdded:Connect(function(Player)
local DataFolder = Instance.new("Folder", Player)
DataFolder.Name = "StatsData"
local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
Focus.Name = "Focus"
local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
Wisdom.Name = "Wisdom"
local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
GoodFaith.Name = "GoodFaith"
local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
BadFaith.Name = "BadFaith"
local success, errormessage = pcall(function() -- IF THERE IS AN ERROR THIS WILL KEEP HE SCRIPT FROM STOPPING
local RetrivedData = DataStore:GetAsync(Player.UserId)
if RetrivedData then
-- YOUR STATS ARE GIVEN BACK HERE vvv
for i, value in pairs(RetrivedData) do
if i == 1 then
Focus.Value = value -- PLAYER IS GIVEN BACK THE FOCUS STAT IF PLAYED BEFORE
elseif i == 2 then
Wisdom.Value = value -- PLAYER IS GIVEN BACK THE WISDOM STAT IF PLAYED BEFORE
elseif i == 3 then
GoodFaith.Value = value -- PLAYER IS GIVEN BACK THE GOOD FAITH STAT IF PLAYED BEFORE
elseif i == 4 then
BadFaith.Value = value -- PLAYER IS GIVEN BACK THE BAD FAITH STAT IF PLAYED BEFORE
end
end
else -- YOU'LL BE GIVEN NOTHING BUT STATS AND A INTRO WHEN YOUR A NEW PLAYER vvv
Focus.Value = 0
Wisdom.Value = 0
GoodFaith.Value = 0
BadFaith.Value = 0
end
end)
if success then
print("SUCCESSFULLY LOADED "..Player.Name.."SAVED DATA")
else
print("COULDN'T LOAD "..Player.Name.." DATA: ")
print(errormessage)
end
end)
game:BindToClose(function()
for i, Player in pairs(game.Players:GetChildren()) do
SaveData(Player)
wait(2)
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY
end)
Hi, I’m not sure if this will be a solution for you, but DataStore:SetAsync(Player.UserId, SaveTable) causes studio to hang because it’s currently saving your data, you have to wait for it to finish before you get out, if it infinitely hangs then try this to go ingame instead and test it, and use a datastore plugin manager or run this snippet of code below in a server script to see if your data saved, check the output in studio or in the developer console ingame to see if it worked, Also do what I stated below otherwise you are just running the function multiple times which causes it to hang longer local RetrivedData = DataStore:GetAsync(502419991) -- This is your userid print(RetrivedData)
I see what you are trying to achieve here
You don’t need this spot below
If you’re only gonna save from a few spots, unless you want it to iterate through the whole thing
It should look like this if you want to save from a few specific values
This and some other pieces of code are still messy, but it should get you started
If you are testing it in roblox studio and stop the session then it doesn’t crash, it’s just because of the wait() in the game:BindToClose(function()
Try this:
local DataStore = game:GetService("DataStoreService"):GetDataStore("Focus_Wisdom_GoodFaith_BadFaith_1")
local RunService = game:GetService("RunService")
local function SaveData(Player)
local Focus = Player:WaitForChild("StatsData"):WaitForChild("Focus").Value
local Wisdom = Player:WaitForChild("StatsData"):WaitForChild("Wisdom").Value
local GoodFaith = Player:WaitForChild("StatsData"):WaitForChild("GoodFaith").Value
local BadFaith = Player:WaitForChild("StatsData"):WaitForChild("BadFaith").Value
local SaveTable = {
["Focus"] = Focus,
["Wisdom"] = Wisdom,
["GoodFaith"] = GoodFaith,
["BadFaith"] = BadFaith
}
local success, err = pcall(function()
DataStore:UpdateAsync(Player.UserId, function(oldData)
return SaveTable
end)
end)
if not success then
warn(err)
end
end
game.Players.PlayerAdded:Connect(function(Player)
local DataFolder = Instance.new("Folder", Player)
DataFolder.Name = "StatsData"
local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
Focus.Name = "Focus"
local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
Wisdom.Name = "Wisdom"
local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
GoodFaith.Name = "GoodFaith"
local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
BadFaith.Name = "BadFaith"
local success, data = pcall(function()
return DataStore:GetAsync(Player.UserId)
end)
if success and data then
Focus.Value = data.Focus
Wisdom.Value = data.Wisdom
GoodFaith.Value = data.GoodFaith
BadFaith.Value = data.BadFaith
elseif not success then
warn("There was an error loading the data for the player: " .. Player.Name)
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY
end)
game:BindToClose(function()
if RunService:IsStudio() then
return
end
for i, Player in pairs(game.Players:GetPlayers()) do
SaveData(Player)
end
end)
Thank you for for helping, I tired the remix you’ve done to my script and it has stopped crashing my studio when I end the session, However it doesn’t save the data. I went in game on a Roblox game client just like you said and gave my self a number value to one of the stats that should be saved. I left the game and printed out the stat and it unfortunately didn’t save and went back to the value 0 as shown here:
Here is me gaining one of the Stat Value and printing out the amount I’ve gained
Here is me after leaving the server and printing the Stat value that I gained in my last session ( which should be 5) which is 0 meaning the Data hasn’t been saved.
I’ve just done the advice you’ve told me to do and everything is perfect however, the Data does not save when the player leaves the game. I’ve tested this out and gave myself the value in the stat ‘Focus’ and left. I joined shortly after to see that my data had not been save and set back to the value 0.
The issue has to do with PlayerRemoving, you have to make sure the thread stays synchronized or “Instant” so to speak, so nothing can wait essentially, you can’t use waitforchild, or wait otherwise it won’t make it through the entire code, and you’ll lose the Player reference to the void.
This may not work still, so be weary of that, it’ll warn you on the first attempt if it can’t find data, but if you rejoin again, it’ll work fine in an ideal situation because then you’ll have data.
local DataStore = game:GetService("DataStoreService"):GetDataStore("Focus_Wisdom_GoodFaith_BadFaith_1")
local RunService = game:GetService("RunService")
local function SaveData(Player)
local StatData = Player.StatsData
local Focus = StatData.Focus.Value
local Wisdom = StatData.Wisdom.Value
local GoodFaith = StatData.GoodFaith.Value
local BadFaith = StatData.BadFaith.Value
local SaveTable = {
["Focus"] = Focus,
["Wisdom"] = Wisdom,
["GoodFaith"] = GoodFaith,
["BadFaith"] = BadFaith
}
local success, err = pcall(function()
DataStore:UpdateAsync(Player.UserId, function(oldData)
return SaveTable
end)
end)
if not success then
warn(err)
end
end
game.Players.PlayerAdded:Connect(function(Player)
local DataFolder = Instance.new("Folder", Player)
DataFolder.Name = "StatsData"
local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
Focus.Name = "Focus"
local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
Wisdom.Name = "Wisdom"
local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
GoodFaith.Name = "GoodFaith"
local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
BadFaith.Name = "BadFaith"
local success, data = pcall(function()
return DataStore:GetAsync(Player.UserId)
end)
if success and data then
Focus.Value = data.Focus
Wisdom.Value = data.Wisdom
GoodFaith.Value = data.GoodFaith
BadFaith.Value = data.BadFaith
elseif not success then
warn("There was an error loading the data for the player: " .. Player.Name)
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY
end)
game:BindToClose(function()
if RunService:IsStudio() then
return
end
for i, Player in pairs(game.Players:GetPlayers()) do
SaveData(Player)
end
end)
Unfortunately, the script didn’t work. but I understand what you say about the script can’t work if you add a ‘WaitForChild’ event to a ‘PlayerRemoving’ function or ‘GameBindToClose’ which makes me believe that where very close to unlocking the mystery to this script and making it work. I’m really do think the script should work but i honestly do not know what it wrong with it. Thank you for the help.
Your script does work. It was me who was in the wrong. I just realised that if I want the data to save I had to make the value change sever sided for it to change. all these time I was making me gain the value client sided. so all I had to do was add a server event and It started to save. sorry for all the problem and thank you.