How is this sending too many DataStore requests?

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)

I’m only using :SetAsync twice, once in the PlayerRemoving, and once in the BindToClose, how could that be sending too many requests?

Thanks!

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)
1 Like

It’s still giving that error.


I can confirm this is the only script using using :SetAsync.

Worked once for me, now it isn’t.
I added prints after each SetAsync, and here’s the output:
image

The one time that it worked, it only printed “Data has been set” once.

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)

Could you try this?

1 Like

Could you explain how that works? From what I’m seeing, the LoadData function is never called and there isn’t a PlayerRemoving function.

Okay look I forgot to connect the functions A

I did a dumb mistake

1 Like

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)

I believe a variable is referenced so that both of the events don’t fire at the same time, so say if I have 2 Events but 1 would only be able to fire:

If I set “Event1” to true, that event would fire but not “Event2”

Same thing with “Event2” and such I believe

Oh… I get it now, I’ll try their code then.

I’m going to take a break apologies if I respond late to anything

change this

game:BindToClose(function()
   wait(5)
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. :sunglasses: (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.

Thanks, but I’ve fixed the issue by using the code provided in the tutorial.