DataStore error breaking features (DataStore request was added to queue)

  1. What do you want to achieve? An obby game with datastore to save player progress and a skip stage developer product.

  2. What is the issue? At first it was working, but then suddenly it stopped working properly.

  3. What solutions have you tried so far? I looked in the developer forum, but I couldn’t really find a solution to my issue. I also tried disabling API Services in Studio and the skip stage developer product still wasn’t working when purchased.

In the beginning it was working as intended, but after several people joined in the game (they weren’t hackers or anything of that sort), the skip stage developer product no longer worked when purchased and after rejoin, everyone was spawning at the lobby. They kept their stage number, but they didn’t spawn at the stage they were at as it used to be, but if they reset, then they would go to the stage they were before leaving.

I also get that warning when I try to purchase the Skip Stage developer product in Studio twice:

Datastore script:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")


local function SavePlayerData(player)

	local success,errormsg = pcall(function()

		local SaveData = {}

		for i,stats in pairs(player.leaderstats:GetChildren()) do

			SaveData[stats.Name] = stats.Value
		end
		SaveDataStore:SetAsync(player.UserId,SaveData)
	end)

	if not success then 
		return errormsg
	end   
end 


Players.PlayerAdded:Connect(function(player)

	local Stats = Instance.new("Folder")
	Stats.Name = "leaderstats"
	Stats.Parent = player

	local Stage = Instance.new("StringValue")
	Stage.Name = "Stage"
	Stage.Parent = Stats
	Stage.Value = 1
	local Data = SaveDataStore:GetAsync(player.UserId)

	if Data then

		print(Data.Stage)

		for i,stats in pairs(Stats:GetChildren()) do

			stats.Value = Data[stats.Name]  
		end   
	else  
		print(player.Name .. " has no data.")   
	end


	player.CharacterAdded:Connect(function(character)

		local Humanoid = character:WaitForChild("Humanoid")
		local Torso = character:WaitForChild("HumanoidRootPart")

		wait()

		if Torso and Humanoid then
			if Stage.Value ~= 0 then

				local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
				Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)     
			end 
		end 
	end)  
end)


Players.PlayerRemoving:Connect(function(player)

	local errormsg = SavePlayerData(player)

	if errormsg then 
		warn(errormsg)  
	end 
end)

game:BindToClose(function()
	for i,player in pairs(Players:GetPlayers()) do 

		local errormsg = SavePlayerData(player)
		if errormsg then
			warn(errormsg)
		end   
	end
	wait(2) 
end)

Skip Stage script:

local martketplace = game:GetService("MarketplaceService")

martketplace.ProcessReceipt = function(receiptinfo)
	local players = game.Players:GetPlayers()
	local finish = 0
	for i=1, #players do
		if players[i].UserId == receiptinfo.PlayerId then
			if receiptinfo.ProductId == 1190837096 and finish == 0 then -- change your product id here at 0000000
				finish = 1 
				players[i].leaderstats.Stage.Value = players[i].leaderstats.Stage.Value + 1
				players[i].Character:MoveTo(game.Workspace.Stages:FindFirstChild(players[i].leaderstats.Stage.Value).Position)
			end
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted
end
1 Like

Hello, sorry for late response. I hope this helps :wink:

I really don’t know why your Stage Spawn code fails since it seems to be written correctly (Maybe you have a spawnlocation at lobby) but about DataStores…

This means (Maybe, since the code in your post, it looks like it only saves data when they leave.) that you’re saving player’s data each time they purcharse the product without a cooldown. In Data Stores you can see in Server Limits that you have to put a cooldown (6 seconds) when repeating a write data function in the same key.

This could also tell about your problem: Players sending lots of DataStore requests, requests being dropped, new data doesn’t save and oof.

Then you have to check when your code saves player’s data, how many times could it save, and regulate it

1 Like

Hello! Sorry to annoy you, but I don’t really know how to do that.

I tried adding wait() in the DataStore script (I’m not even sure if that’s the right thing to do), but it didn’t work.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")


local function SavePlayerData(player)

	local success,errormsg = pcall(function()

		local SaveData = {}

		for i,stats in pairs(player.leaderstats:GetChildren()) do

			SaveData[stats.Name] = stats.Value
		end
		SaveDataStore:SetAsync(player.UserId,SaveData)
	end)

	if not success then 
		return errormsg
	end
	--- wait(6)
end 


Players.PlayerAdded:Connect(function(player)

	local Stats = Instance.new("Folder")
	Stats.Name = "leaderstats"
	Stats.Parent = player

	local Stage = Instance.new("StringValue")
	Stage.Name = "Stage"
	Stage.Parent = Stats
	Stage.Value = 1
	local Data = SaveDataStore:GetAsync(player.UserId)

	if Data then
    --- wait(6)
		print(Data.Stage)

		for i,stats in pairs(Stats:GetChildren()) do

			stats.Value = Data[stats.Name]  
		end   
	else  
		print(player.Name .. " has no data.")   
	end


	player.CharacterAdded:Connect(function(character)

		local Humanoid = character:WaitForChild("Humanoid")
		local Torso = character:WaitForChild("HumanoidRootPart")

		wait()

		if Torso and Humanoid then
			if Stage.Value ~= 0 then

				local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
				Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)     
			end 
		end 
	end)  
end)


Players.PlayerRemoving:Connect(function(player)
	local errormsg = SavePlayerData(player)
	--- wait(6)
	if errormsg then 
		warn(errormsg)  
	end 
end)

game:BindToClose(function()
	for i,player in pairs(Players:GetPlayers()) do 
		local errormsg = SavePlayerData(player)
		--- wait(6)
		if errormsg then
			warn(errormsg)
		end   
	end
	wait(2) 
end)

You don’t have to modify your functions or adding wait(6) inside of them, just add wait(6) where your code can call DataStore requests too often, for example:

-- This code is poop, don't even try to adapt it to your system
-- It's just an example

local Bool = true -- Using a boolean  to yield
Event:Connect(function() -- DataStore requests can be called too often in this event
	if Bool then
	   Bool = false
	   SaveDataFunction()
	   Bool = true
	else
	   wait(6)
	   SaveDataFunction()
	   Bool = true
	end
end

You should check these posts which helped me when I had a similar problem.

1 Like