Hello!
I was helping my friend with his game until I ran a problem.
While trying to make datastore, when it increases the amount by 10 or 5, it resets back to 0 and does not save!
I’m new to making datastore so there may be a lot of errors.
Script
--- Add Leaderstats ---
game:GetService("Players").PlayerAdded:Connect(function(Player)
local Folder = Instance.new("Folder", Player)
Folder.Name = "leaderstats"
local NumberValue = Instance.new("NumberValue", Folder)
NumberValue.Name = "Studs"
end)
--- Add Studs/minute and Save Currency ---
game:GetService("Players").PlayerAdded:Connect(function(Player)
local NumberValue = Player:WaitForChild("leaderstats").Studs
local DataStore = game:GetService("DataStoreService")
local GameDataStore = DataStore:GetDataStore("GameDataStore")
local Data
if Player.MembershipType == Enum.MembershipType.None then
while wait(60) do
Player.leaderstats.Studs.Value += 5
wait(1)
local Success, ErrorMessage = pcall(function()
Data = GameDataStore:GetAsync(Player.UserId.."-NumberValue")
end)
if Success then
NumberValue.Value = Data
else
local GUI = Player:WaitForChild("PlayerGui").DataSaveFailed
GUI.TextLabel.Visible = true
warn("Saving for player ||"..Player.Name.."|| failed!")
end
end
elseif Player.MembershipType == Enum.MembershipType.Premium then
while wait(30) do
Player.leaderstats.Studs.Value += 10
wait(1)
local Success, ErrorMessage = pcall(function()
Data = GameDataStore:GetAsync(Player.UserId.."-NumberValue")
end)
if Success then
NumberValue.Value = Data
else
local GUI = Player:WaitForChild("PlayerGui").DataSaveFailed
GUI.TextLabel.Visible = true
warn("Saving for player ||"..Player.Name.."|| failed!")
end
end
end
end)
--- Save Currency When Player Is Leaving ---
game:GetService("Players").PlayerRemoving:Connect(function(Player)
local NumberValue = Player.leaderstats.Studs
local DataStore = game:GetService("DataStoreService")
local GameDataStore = DataStore:GetDataStore("GameDataStore")
local Success, ErrorMessage = pcall(function()
GameDataStore:SetAsync(Player.UserId.."-NumberValue", Player.leaderstats.Studs.Value)
end)
if Success then
print("Data for player ||"..Player.Name.."|| was saved succesfully!")
else
warn("Saving data upon leaving for player ||"..Player.Name.."|| failed!")
end
end)
I’ve messed with your code a bit and compiled a list of problems I saw, both opinionated and technical.
Two functions for playeradded is redundant and may cause one or the other to not register
I personally recommend avoiding inescapable loops (event based code instead of repeat until / while true/wait do) and the use of task.wait() (Uses heartbeat) instead of wait() due to this, I’ve changed it to a task.delay with a looping function call per player.
It appears originally every give you would getasync on the saved value, set it to that before saving, then save the new value causing a loop with no progress (you could only get to 5) to compound this, you also did not set the studs value from cache on join resulting in the appearance of a reset (values were still saved behind the scenes)
I may also add that saving / fetching the datastore every give is not an efficient way to do datastore. I recommend doing it ONLY when the player leaves
I have added functionality to kick the player upon unsuccessfully retrieving data as a safeguard to data loss. (can be removed in line 30)
ALSO: Make sure you turn on studio datastore access in studio if you want to test this in studio.
No need to fret, I’ve already tested this and can confirm it works. This should go in serverscriptservice.
Script
--- Leaderstats / Add Studs/minute and Save Currency ---
game.Players.PlayerAdded:Connect(function(plr)
Instance.new("Folder",plr).Name = "leaderstats"
Instance.new("NumberValue",plr:WaitForChild("leaderstats")).Name = "Studs"
local gds = game:GetService("DataStoreService"):GetDataStore("GameDataStore")
local togive
local s,e = pcall(function()
togive = gds:GetAsync(plr.UserId)
end)
if s then
print("Data for player ||"..plr.Name.."|| was fetched succesfully!")
plr.leaderstats.Studs.Value = togive
local basetime = 60
local baseamt = 5
if plr.MembershipType == Enum.MembershipType.Premium then
basetime /= 2
baseamt *= 2
end
local function give()
plr.leaderstats.Studs.Value += baseamt
end
local function loop()
task.delay(basetime,function()
give()
task.wait(0.1)
loop()
end)
end
loop()
else
warn("Saving data upon leaving for player ||"..plr.Name.."|| failed! || " .. e)
plr:Kick("Failed to fetch datastore. Please try again. If this issue persists, contact the developer.")
end
end)
--- Save Currency When Player Is Leaving ---
game.Players.PlayerRemoving:Connect(function(plr)
local gds = game.DataStoreService:GetDataStore("GameDataStore")
local s,e = pcall(function()
gds:SetAsync(plr.UserId,plr.leaderstats.Studs.Value)
end)
if s then
print("Data for player ||"..plr.Name.."|| was saved succesfully!")
else
warn("Saving data upon leaving for player ||"..plr.Name.."|| failed! || " .. e)
end
end)