I don’t know how this code is sending too many requests to the DataStore.
Code:
local rs = game:GetService("ReplicatedStorage")
local DSS = game:GetService("DataStoreService")
local dataStores = DSS:GetDataStore("SwordFightStore")
local defaultcash = 0
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
if character then
character.Humanoid.WalkSpeed = 16
character.Humanoid.MaxHealth = 250
character.Humanoid.Health = character.Humanoid.MaxHealth
end
character.Humanoid.Died:Connect(function()
if character.Humanoid and character.Humanoid:FindFirstChild("creator") then
rs:WaitForChild("KillFeed").Value = tostring(character.Humanoid.creator.Value) .. " killed ".. player.Name
end
if character:FindFirstChild("GameTag") then
character.GameTag:Destroy()
end
wait(0.1)
player:LoadCharacter()
end)
end)
local player_data
local success, errormessage = pcall(function()
player_data = dataStores:GetAsync(player.UserId.."-coins")
end)
if success then else print(errormessage)end
if player_data ~= nil then
-- has data, load it!
coins.Value = player_data
else
coins.Value = defaultcash
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local success, errormessage = pcall(function()
dataStores:SetAsync(player.UserId.."-coins", player.leaderstats.Coins.Value)
end)
if success then else print(errormessage)end
end)
game:BindToClose(function()
for i,player in pairs(game.Players:GetPlayers()) do
local success, errormessage = pcall(function()
dataStores:SetAsync(player.UserId.."-coins", player.leaderstats.Coins.Value)
end)
if success then else print(errormessage)end
end
end)
BindToClose() & PlayerRemoving() seem to fire both at the same time, could you maybe try adding a wait(5) inside these lines here?
game:BindToClose(function()
for i,player in pairs(game.Players:GetPlayers()) do
wait(5)
local success, errormessage = pcall(function()
dataStores:SetAsync(player.UserId.."-coins", player.leaderstats.Coins.Value)
end)
if success then else print(errormessage)end
end
end)
Hm, you could possibly try using a coroutine to yield so that’ll save all the players using local functions?
local rs = game:GetService("ReplicatedStorage")
local DSS = game:GetService("DataStoreService")
local dataStores = DSS:GetDataStore("SwordFightStore")
local defaultcash = 0
local function LoadData(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
if character then
character.Humanoid.WalkSpeed = 16
character.Humanoid.MaxHealth = 250
character.Humanoid.Health = character.Humanoid.MaxHealth
end
character.Humanoid.Died:Connect(function()
if character.Humanoid and character.Humanoid:FindFirstChild("creator") then
rs:WaitForChild("KillFeed").Value = tostring(character.Humanoid.creator.Value) .. " killed ".. player.Name
end
if character:FindFirstChild("GameTag") then
character.GameTag:Destroy()
end
wait(0.1)
player:LoadCharacter()
end)
end)
local player_data
local success, errormessage = pcall(function()
player_data = dataStores:GetAsync(player.UserId.."-coins")
end)
if success then else print(errormessage)end
if player_data ~= nil then
-- has data, load it!
coins.Value = player_data
else
coins.Value = defaultcash
end
end)
local function SaveData(player)
local success, errormessage = pcall(function()
dataStores:SetAsync(player.UserId.."-coins", player.leaderstats.Coins.Value)
end)
if success then else print(errormessage)end
end)
game.Players.PlayerAdded:Connect(LoadData)
game.Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(function()
for i,player in pairs(game.Players:GetPlayers()) do
coroutine.wrap(SaveData)(player)
end
end)
I added a print statement, and it’s not printing when I leave…
(print statement is in DataSave function)
local rs = game:GetService("ReplicatedStorage")
local DSS = game:GetService("DataStoreService")
local dataStores = DSS:GetDataStore("SwordFightStore")
local defaultcash = 0
local function LoadData(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
if character then
character.Humanoid.WalkSpeed = 16
character.Humanoid.MaxHealth = 250
character.Humanoid.Health = character.Humanoid.MaxHealth
end
character.Humanoid.Died:Connect(function()
if character.Humanoid and character.Humanoid:FindFirstChild("creator") then
rs:WaitForChild("KillFeed").Value = tostring(character.Humanoid.creator.Value) .. " killed ".. player.Name
end
if character:FindFirstChild("GameTag") then
character.GameTag:Destroy()
end
wait(0.1)
player:LoadCharacter()
end)
end)
local player_data
local success, errormessage = pcall(function()
player_data = dataStores:GetAsync(player.UserId.."-coins")
end)
if success then else print(errormessage)end
if player_data ~= nil then
-- has data, load it!
coins.Value = player_data
else
coins.Value = defaultcash
end
end
local function SaveData(player)
local success, errormessage = pcall(function()
dataStores:SetAsync(player.UserId.."-coins", player.leaderstats.Coins.Value)
end)
if success then print("dataSave") else print(errormessage)end
end
game.Players.PlayerAdded:Connect(LoadData)
game.Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(function()
for i,player in pairs(game.Players:GetPlayers()) do
coroutine.wrap(SaveData)(player)
end
end)
I’m following a tutorial, and for the BindToClose, they created a BindableEvent and some PlayersLeft thing. I didn’t really get how it works, so I didn’t use it, could you explain?
Their code:
game.Players.PlayerRemoving:Connect(function(player)
pcall(function()
-- blah blah save data stuff I do not want to type out
PlayersLeft -= 1
bindableEvent:Fire()
end)
end)
game:BindToClose(function()
while playersLeft > 0 do
bindableEvent.Event:Wait() -- what???
end
end)
SetAsync is just an easier way to save a datastore. SetAsync is intended to just add a value or do something else and not saving at all. With SetAsync, saving a value to the datastore right after the value changed will be a little delayed, thus, the datastore loads only the value before the change.
Example: User A has 100 coins after selling it. In 0.5 seconds, he left the game in an epic manner. (Lmao). When he came back, his coins is 0 instead of 100. He cried.
It is recommended to use UpdateAsync. Note, you can’t just replace SetAsync with UpdateAsync in your code. You need to make a whole new datastore script for the UpdateAsync.