need help fixing this
local datastore = game:GetService("DataStoreService") local ds1 = datastore:GetDataStore("KillsSaveSystem") local ds2 = datastore:GetDataStore("CashSavSsystem") player = game.Players
game.Players.PlayerAdded:connect(function(player) local lb = Instance.new("Folder", player) lb.Name = "leaderstats" local Kills = Instance.new("IntValue", lb) Kills.Name = "Kills" local Cash = Instance.new("IntValue", lb) Cash.Name = "Cash"
Kills.Value = ds1:GetAsync(player.UserId) ds1:SetAsync(player.UserId, game.Players.leaderstats.Kills.Value) Cash.Value = ds1:GetAsync(player.UserId) ds2:SetAsync(player.UserId, game.Players.leaderstats.Cash.Value) Kills.Changed:connect(function() ds1:SetAsync(player.UserId, game.Players.leaderstats.Kills.Value) Cash.Changed:connect(function() ds2:SetAsync(player.UserId, game.Players.leaderstats.Cash.Value) end) end)
end)
As what @pwx said, you shouldn't save a value whenever it is changed since you will cause stress to the server (it might break the game) and just save it whenever the player leaves instead.
Also, when using :SetAsync()
and :GetAsync()
, it might cause errors and eventually break the whole game. To fix this, you need to use a pcall()
so that if anything errors, it will be returned by the pcall()
and won't be printed in the output (which won't break the game!)
Here's a tip: You don't need to create a DataStore for each value, you can just store them in a table and save the table.
local datastore = game:GetService("DataStoreService") local ds = datastore:GetDataStore("SaveSystem") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local function waitForRequestBudget(requestType: Enum.DataStoreRequestType) local currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) while currentBudget < 1 do currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) task.wait(5) end end local function loadData(player) local lb = Instance.new("Folder", player) lb.Name = "leaderstats" local Kills = Instance.new("IntValue", lb) Kills.Name = "Kills" local Cash = Instance.new("IntValue", lb) Cash.Name = "Cash" waitForRequestBudget(Enum.DataStoreRequestType.GetAsync) -- we will use this to avoid errors local success, data = pcall(function() return ds:GetAsync(player.UserId) end) if success and data then Kills.Value = data.Kills Cash.Value = data.Cash else print("Player " .. player.Name .. " has no data saved.") warn(data) -- warns the error end end local function saveData(player, dontWait) local lb = player.leaderstats local data = { ["Kills"] = lb.Kills.Value, ["Cash"] = lb.Cash.Value } local success repeat if not dontWait then -- if game not shutting down waitForRequestBudget(Enum.DataStoreRequestType.UpdateAsync) -- we will use this to avoid errors end -- use :UpdateAsync() instead of :SetAsync() success = pcall(function() ds:UpdateAsync(player.UserId, function() -- saved data return data end) end) until success -- looping this until datta saved successfully end for _, player in ipairs(Players:GetPlayers()) do coroutine.wrap(loadData)(player) end Players.PlayerAdded:Connect(loadData) -- when player joins the game Players.PlayerRemoving:Connect(saveData) -- when player is leaving the game game:BindToClose(function() -- when the game shuts down if RunService:IsStudio() then -- if the game is on Roblox Studio task.wait(2) -- we will wait 2 seconds and it will fire the .PlayerRemoving event else -- if not local finished = Instance.new("BindableEvent") -- we will use this wait for everyone's data to save local allPlayers = Players:GetPlayers() -- gets every player in the server local leftPlayers = #allPlayers -- number of players left in the server for _, player in ipairs(allPlayers) do coroutine.wrap(function() saveData(player, true) leftPlayers -= 1 -- decreasing the amount of players whose data haven't been saved yet if leftPlayers == 0 then -- if no players left finished:Fire() end end)() end finished.Event:Wait() end end)