Donation Value DataStore Save Not Working?

Hello Developers,

I am having an issue with my datastore not saving or not properly getting the datastore (I haven’t tested it with a print statement yet to see where the issue is). I have read the code multiple times, however, I can’t seem to find where issue might be, any help will be appreciated! My code: `local DataStoreService = game:GetService(“DataStoreService”)
local Players = game:GetService(“Players”)
local RunService = game:GetService(“RunService”)

local function waitForRequestBudget(requestType)
local currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType)

while currentBudget < 1 do
	currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType)
	wait(5)
end

end

local function safeCall(playerName, func, self, requestType, …)
local success, ret

repeat
	if requestType then
		waitForRequestBudget(requestType) 
	end
	success, ret = pcall(func, self, ...)

	if not success then
		print("Error: " .. ret)
		if string.find(ret, "501") or string.find(ret, "504") then
			return
		end
	end
until (success) or (playerName and not Players:FindFirstChild(playerName))

return success, ret

end

local function setUp(player)
local name = player.Name
local userId = player.UserId
local key = “Player_” … userId

local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"

local Tix = Instance.new("IntValue")
Tix.Name = "Tix"
local Donation = Instance.new("IntValue")
Donation.Name = "Donated"
local Donated = Instance.new("IntValue")
Donated.Name = "Donated"

local dataStore = DataStoreService:GetDataStore(key)
local dataStore2 = DataStoreService:GetDataStore("Donation")
local orderedDataStore = DataStoreService:GetOrderedDataStore(key)
local orderedDataStore2 = DataStoreService:GetOrderedDataStore("Donation")

local _, pages = safeCall(name, orderedDataStore.GetSortedAsync, orderedDataStore, Enum.DataStoreRequestType.GetSortedAsync, false, 100)
local _, pages2 = safeCall(name, orderedDataStore2.GetSortedAsync, orderedDataStore2, Enum.DataStoreRequestType.GetSortedAsync, false, 100)
local currentPage = pages:GetCurrentPage()
local currentPage2 = pages2:GetCurrentPage()

if #currentPage > 0 then
	for _, dataStoreKey in ipairs(currentPage) do
		if not Players:FindFirstChild(name) then return end
		dataStoreKey = dataStoreKey.value
		local success, ret = safeCall(name, dataStore.GetAsync, dataStore, Enum.DataStoreRequestType.GetAsync, dataStoreKey)

		if success then
			Tix.Value = ret
			Tix.Parent = leaderstats
			leaderstats.Parent = player
			break
		end
	end
else
	Tix.Value = 0
	Tix.Parent = leaderstats
	leaderstats.Parent = player
end

if #currentPage2 > 0 then
	for _, dataStoreKey2 in ipairs(currentPage2) do
		if not Players:FindFirstChild(name) then return end
		dataStoreKey2 = dataStoreKey2.value
		local success, ret = safeCall(name, dataStore2.GetAsync, dataStore2, Enum.DataStoreRequestType.GetAsync, dataStoreKey2)

		if success then
			Donated.Value = ret
			Donated.Parent = leaderstats
			leaderstats.Parent = player
			break
		end
	end
else
	Donated.Value = 0
	Donated.Parent = leaderstats
	leaderstats.Parent = player
end

end

local function save(player, dontWait)
local userId = player.UserId
local key = “Player_” … userId
local leaderstats = player:FindFirstChild(“leaderstats”)

if leaderstats then
	local TixValue = leaderstats:WaitForChild("Tix").Value
	local DonationValue = leaderstats:WaitForChild("Donated").Value
	
	local dataStore = DataStoreService:GetDataStore(key)
	local dataStore2 = DataStoreService:GetDataStore("Donation")
	local orderedDataStore = DataStoreService:GetOrderedDataStore(key)
	local orderedDataStore2 = DataStoreService:GetOrderedDataStore("Donation")

	local _, pages = safeCall(nil, orderedDataStore.GetSortedAsync, orderedDataStore, Enum.DataStoreRequestType.GetSortedAsync, false, 1)
	local _, pages2 = safeCall(nil, orderedDataStore2.GetSortedAsync, orderedDataStore2, Enum.DataStoreRequestType.GetSortedAsync, false, 1)
	local latest = pages:GetCurrentPage()[1] or 0
	local latest2 = pages2:GetCurrentPage()[1] or 0
	local should = (type(latest) == "table" and latest.value or 0) + 1
	local should2 = (type(latest2) == "table" and latest2.value or 0) + 1


	safeCall(nil, orderedDataStore.UpdateAsync, orderedDataStore, (not dontWait and Enum.DataStoreRequestType.UpdateAsync), should, function()
		return should
	end)
	safeCall(nil, dataStore.UpdateAsync, dataStore, (not dontWait and Enum.DataStoreRequestType.UpdateAsync), should, function()
		return TixValue
	end)
	safeCall(nil, orderedDataStore2.UpdateAsync, orderedDataStore2, (not dontWait and Enum.DataStoreRequestType.UpdateAsync), should2, function()
		return should2
	end)
	safeCall(nil, dataStore2.UpdateAsync, dataStore2, (not dontWait and Enum.DataStoreRequestType.UpdateAsync), should2, function()
		return DonationValue
	end)
end

end

local function onShutdown()
if RunService:IsStudio() then
task.wait(2)
else
local finished = Instance.new(“BindableEvent”)
local allPlayers = Players:GetPlayers()
local leftPlayers = #allPlayers

	for _,player in ipairs(allPlayers) do
		coroutine.wrap(function()
			save(player, true)
			leftPlayers -= 1
			if leftPlayers == 0 then
				finished:Fire()
			end
		end)()
	end

	finished.Event:Wait()
end

end

for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(setUp)(player)
end

Players.PlayerAdded:Connect(setUp)
Players.PlayerRemoving:Connect(save)
game:BindToClose(onShutdown)

while true do
wait(60)
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(save)(player)
end
end`

This Should work

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

-- Constants
local SAVE_INTERVAL = 60 -- Save data every 60 seconds
local DATA_STORE_NAME = "PlayerData" -- Main data store
local DONATION_STORE_NAME = "DonationData" -- Donation tracking store

-- Wait until we have budget for a DataStore request
local function waitForRequestBudget(requestType)
	local currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType)

	while currentBudget < 1 do
		currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType)
		task.wait(5)
	end
end

-- Safely call DataStore methods with error handling
local function safeCall(playerName, func, self, requestType, ...)
	local success, ret
	local maxRetries = 3
	local retriesLeft = maxRetries

	repeat
		if requestType then
			waitForRequestBudget(requestType) 
		end
		
		success, ret = pcall(func, self, ...)

		if not success then
			print("DataStore Error: " .. ret)
			
			-- Handle specific error codes
			if string.find(ret, "501") or string.find(ret, "504") then
				-- Server rejected request or timed out, no need to retry
				return false, ret
			elseif string.find(ret, "502") or string.find(ret, "403") then
				-- Rate limited or permission issue, wait longer
				task.wait(10)
			end
			
			retriesLeft = retriesLeft - 1
			task.wait(1)
		end
	until (success) or (retriesLeft <= 0) or (playerName and not Players:FindFirstChild(playerName))

	return success, ret
end

-- Set up player's leaderstats
local function setUp(player)
	local name = player.Name
	local userId = player.UserId
	local key = "Player_" .. userId

	-- Create leaderstats folder
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	-- Create stats
	local tix = Instance.new("IntValue")
	tix.Name = "Tix"
	tix.Value = 0
	
	local donated = Instance.new("IntValue")
	donated.Name = "Donated"
	donated.Value = 0
	
	-- Parent stats to leaderstats
	tix.Parent = leaderstats
	donated.Parent = leaderstats
	leaderstats.Parent = player
	
	-- Get data stores
	local playerDataStore = DataStoreService:GetDataStore(DATA_STORE_NAME)
	local donationDataStore = DataStoreService:GetDataStore(DONATION_STORE_NAME)
	
	-- Load player data
	local success, playerData = safeCall(name, playerDataStore.GetAsync, playerDataStore, Enum.DataStoreRequestType.GetAsync, key)
	
	if success and playerData then
		-- Set values from saved data
		if playerData.Tix then
			tix.Value = playerData.Tix
		end
		
		if playerData.Donated then
			donated.Value = playerData.Donated
		end
	end
	
	print("Data loaded for player: " .. name)
end

-- Save player data
local function save(player, isUrgent)
	local userId = player.UserId
	local key = "Player_" .. userId
	local leaderstats = player:FindFirstChild("leaderstats")
	
	if not leaderstats then
		return
	end
	
	local tix = leaderstats:FindFirstChild("Tix")
	local donated = leaderstats:FindFirstChild("Donated")
	
	if not (tix and donated) then
		return
	end
	
	-- Prepare data table
	local playerData = {
		Tix = tix.Value,
		Donated = donated.Value
	}
	
	-- Get data stores
	local playerDataStore = DataStoreService:GetDataStore(DATA_STORE_NAME)
	local donationDataStore = DataStoreService:GetDataStore(DONATION_STORE_NAME)
	
	-- Define request type based on urgency
	local requestType = isUrgent and nil or Enum.DataStoreRequestType.SetAsync
	
	-- Save player data
	local success, errorMessage = safeCall(player.Name, playerDataStore.SetAsync, playerDataStore, requestType, key, playerData)
	
	if success then
		print("Data saved for player: " .. player.Name)
	else
		warn("Failed to save data for player: " .. player.Name .. " | Error: " .. tostring(errorMessage))
	end
	
	-- Update global donation leaderboard if needed
	if donated.Value > 0 then
		local donationKey = "Donation_" .. userId
		safeCall(player.Name, donationDataStore.SetAsync, donationDataStore, requestType, donationKey, donated.Value)
	end
end

-- Handle game shutdown
local function onShutdown()
	print("Game shutting down, saving all player data...")
	
	if RunService:IsStudio() then
		task.wait(2)
	else
		local finished = Instance.new("BindableEvent")
		local allPlayers = Players:GetPlayers()
		local leftPlayers = #allPlayers
		
		if leftPlayers == 0 then
			return
		end
		
		for _, player in ipairs(allPlayers) do
			task.spawn(function()
				save(player, true)
				leftPlayers = leftPlayers - 1
				if leftPlayers == 0 then
					finished:Fire()
				end
			end)
		end
		
		finished.Event:Wait()
		print("All player data saved successfully")
	end
end

-- Auto-save all players periodically
local function autoSave()
	while true do
		task.wait(SAVE_INTERVAL)
		print("Auto-saving all player data...")
		
		for _, player in ipairs(Players:GetPlayers()) do
			task.spawn(function()
				save(player)
			end)
		end
	end
end

-- Initialize existing players (in case of script reload)
for _, player in ipairs(Players:GetPlayers()) do
	task.spawn(setUp, player)
end

-- Connect events
Players.PlayerAdded:Connect(setUp)
Players.PlayerRemoving:Connect(function(player)
	save(player, true)
end)
game:BindToClose(onShutdown)

-- Start auto-save loop
task.spawn(autoSave)

SetAsync is not a valid member of “Enum.DataStoreRequestType” - Server - TixHandler:126

1 Like