My data stores dont work in roblox studio (API services is on)

heres the problem, the script that saves the data is working perfecly fine but sometimes when i leave it does not save, this issue i believe is just on roblox studio but i dont want it to effect my game when published, most of the data store scripts dont save when the player leaves and sometimes save , heres 1 example of the data store that is the most important one in my game

local datastoreservice = game:GetService("DataStoreService")

local MoneyDataStore = datastoreservice:GetDataStore("MoneyDataStore")

local players = game.Players



players.PlayerAdded:Connect(function(plr)

	local leaderstats = Instance.new("Folder")

	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("IntValue")

	Cash.Parent = leaderstats
	Cash.Name = "Cash"

	local Bank = Instance.new("IntValue")

	Bank.Parent = leaderstats
	Bank.Name = "Bank"


	local data

	local successfull, errormessage = pcall(function()

		data = MoneyDataStore:GetAsync(plr.UserId)

	end)	

	if successfull and data then

		Cash.Value = data.Cash
		Bank.Value = data.Bank

		print("Data Loaded Successfully")

	else

		Cash.Value = 100
		Bank.Value = 100

		warn(errormessage)

	end

end)

players.PlayerRemoving:Connect(function(plr)

	local successfull, errormessage = pcall(function()

		local data = {

			Bank = plr.leaderstats.Bank.Value;

			Cash = plr.leaderstats.Cash.Value;

		}

		MoneyDataStore:SetAsync(plr.UserId, data)

	end)	

	if successfull then

		print("Data Saved Successfully")

	else

		print("Encountered An Error While Saving Data")
	end

end)

Hey!

It really shouldn’t be too hard to fix. The code looks perfectly fine, it’s just that everything is processing so fast that sometimes the data doesn’t load/save. I would recommand adding a wait() after the player was added to make sure the player is fully loaded. I also changed a couple other things to your code to prevent glitches like this. (Most of the changes were made after the player was removed).

local players = game:GetService("Players")
local datastoreservice = game:GetService("DataStoreService")

local MoneyDataStore = datastoreservice:GetDataStore("MoneyDataStore")

players.PlayerAdded:Connect(function(plr)
	wait()

	local leaderstats = Instance.new("Folder")

	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("IntValue")

	Cash.Parent = leaderstats
	Cash.Name = "Cash"

	local Bank = Instance.new("IntValue")

	Bank.Parent = leaderstats
	Bank.Name = "Bank"


	local data

	local successfull, errormessage = pcall(function()

		data = MoneyDataStore:GetAsync(plr.UserId)

	end)

	if successfull and data then

		Cash.Value = data["Cash"]
		Bank.Value = data["Bank"]

		print("Data Loaded Successfully")

	else

		Cash.Value = 100
		Bank.Value = 100

		warn(errormessage)

	end
end)

players.PlayerRemoving:Connect(function(plr)
	
	local Cash = plr:FindFirstChild("leaderstats").Cash
	local Bank = plr:FindFirstChild("leaderstats").Bank

	local successfull, errormessage = pcall(function()

		local data = {

			["Bank"] = Bank.Value;

			["Cash"] = Cash.Value;

		}

		MoneyDataStore:SetAsync(plr.UserId, data)

	end)	
	
	if successfull then

		print("Data Saved Successfully")

	else

		print("Encountered An Error While Saving Data")
	end

end)

I hope this helps! If you need any more information, make sure to let me know :wink:

This doesn’t matter! When the player joins the game, instances can still be created within the player instance and data can still be retrieved / saved! If anything, adding a wait() could lead to a race condition (maybe not in this context depending on the yield time for data to be retrieved).

Testing datastores in studio might get finnicky. When you stop the testing session, the player doesn’t actually leave, but the game closes. I would recommend using a function called BindToClose, which is a built-in function that is called prior to a game shutting down. I would highly suggest you keep this in your game code as well, not just for testing purposes.

You can use this function to save the data of every player in the game before the game gets shut down (using a for loop). I will write out some code for you to understand how this works!

-- Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local MoneyDataStore = DataStoreService:GetDataStore("MoneyDataStore")

-- Load player data
local function loadData(plr)
    -- Create leaderstats
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"

    local Cash = Instance.new("IntValue")
    Cash.Name = "Cash"
	Cash.Parent = leaderstats

    local Bank = Instance.new("IntValue")
    Bank.Name = "Bank"
	Bank.Parent = leaderstats
	
    -- Retrieve data
    local data
    local successful, errormessage = pcall(function()
		data = MoneyDataStore:GetAsync(plr.UserId)
	end)

    -- Set values of leaderstats after data loaded
    if successful then
        Cash.Value = data["Cash"]
		Bank.Value = data["Bank"]
    else
        Cash.Value = 100
		Bank.Value = 100
		warn(errormessage)
    end

    -- Parent leaderstats to player after data loaded
    leaderstats.Parent = plr
end



-- Save player data
local function saveData(plr)
    -- Get leaderstats data
    local Cash = plr:FindFirstChild("leaderstats").Cash
	local Bank = plr:FindFirstChild("leaderstats").Bank

    -- Save data
    local data = {
        ["Bank"] = Bank.Value;
        ["Cash"] = Cash.Value;
    }
    local successfull, errormessage = pcall(function()
		MoneyDataStore:SetAsync(plr.UserId, data)
	end)

    -- Prints
    if successfull then
		print("Data Saved Successfully")
	else
		print("Encountered An Error While Saving Data")
    end
end

-- Load / Save player data on join / leave
Players.PlayerAdded:Connect(loadData)
Players.PlayerRemoving:Connect(saveData)

-- Save all players' data when game closes
game:BindToClose(function()
    for _, player in Players:GetPlayers() do
        task.spawn(function()
            saveData(player)
        end)
    end
end)

now it just dosent work anymore, the data store did not save at all for some reason?
sorry for the late respond though

Try to write this :

local datastoreservice = game:GetService("DataStoreService")

local MoneyDataStore = datastoreservice:GetDataStore("MoneyDataStore")

local players = game.Players



players.PlayerAdded:Connect(function(plr)

	local leaderstats = Instance.new("Folder")

	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("IntValue")

	Cash.Parent = leaderstats
	Cash.Name = "Cash"

	local Bank = Instance.new("IntValue")

	Bank.Parent = leaderstats
	Bank.Name = "Bank"

	local successfull, data = pcall(function()
		 return MoneyDataStore:GetAsync(plr.UserId)
	end)	

	if successfull and data then
		Cash.Value = data["Cash"]
		Bank.Value = data["Bank"]

		print("Data Loaded Successfully")
	else

		Cash.Value = 100
		Bank.Value = 100

		warn("Cannot load data for", plr.Name)

	end

end)

players.PlayerRemoving:Connect(function(plr)

	local successfull, errormessage = pcall(function()

		local data = {
			["Bank"] = plr.leaderstats.Bank.Value;
			["Cash"] = plr.leaderstats.Cash.Value;
		}

		MoneyDataStore:SetAsync(plr.UserId, data)
	end)	

	if successfull then
		print("Data Saved Successfully")
	else
		print("Encountered An Error While Saving Data")
		warn(errormessage)
	end

end)

that worked for now, ill let you know when it dosent glitch after a few tries, can you please tell me what have you change to make it work?

So instead of :

local data = {
	Bank = plr.leaderstats.Bank.Value;
	Cash = plr.leaderstats.Cash.Value;
}

I wrote :

local data = {
	["Bank"] = plr.leaderstats.Bank.Value;
	["Cash"] = plr.leaderstats.Cash.Value;
}

welp bad news sir, i just tested it a couple of times and nope it didnt work… it makes the value 0 instead of loading it… idk whats the problem

Did your script is a local script or a server script ? I’m stupid asking this but anyway. And what is the parent of the script ?

no its ok , its a sever script in a serverscriptservice in a folder where i keep all my data store scripts

Alright try this :

local datastoreservice = game:GetService("DataStoreService")

local MoneyDataStore = datastoreservice:GetDataStore("MoneyData")

local players = game.Players

players.PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")

	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("NumberValue")
	Cash.Parent = leaderstats
	Cash.Name = "Cash"
	Cash.Value = 0
	
	local Bank = Instance.new("NumberValue")
	Bank.Parent = leaderstats
	Bank.Name = "Bank"
	Cash.Value = 0

	local sucess, data, att = nil, nil, 1

	repeat
		sucess, data = pcall(function()
			return MoneyDataStore:GetAsync(plr.UserId)
		end)

		if not sucess then
			warn("Cannot load data for", plr.Name)
			task.wait(3)
		end
		att += 1
	until sucess or att == 5

	if sucess then
		print("Data Loaded Successfully")
		
		if data then
			Cash.Value = data["Cash"]
			Bank.Value = data["Bank"]
		end
	else
		warn("Cannot load data")
		plr:Kick("Cannot load your data, please retry later")
	end

end)

players.PlayerRemoving:Connect(function(plr)
	local success, err, att = nil, nil, 1
	
	local data = {}
	
	repeat
		success, err = pcall(function()
			data = {
				["Bank"] = plr.leaderstats.Bank.Value;
				["Cash"] = plr.leaderstats.Cash.Value;
			}

			MoneyDataStore:SetAsync(plr.UserId, data)
		end)
		
		if not success then
			warn(err)
			task.wait(3)
		end
		att += 1
	until success or att == 5

	if success then
		print("Data Saved Successfully")
	else
		print("Encountered An Error While Saving Data")
		warn(err)
	end
end)

Also change the data store name to your data store i changed it

Fixed it! Sorry, I wrote it on the fly.

There were two problems:

  1. In the case that the player’s data doesn’t exist (which means they are new to the game), you won’t be able to index data.Cash or data.Bank.
  2. I forgot to add a wait after the BindToClose() function!
-- Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local MoneyDataStore = DataStoreService:GetDataStore("MoneyDataStore")

-- Load player data
local function loadData(plr)
	-- Create leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"

	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = leaderstats

	local Bank = Instance.new("IntValue")
	Bank.Name = "Bank"
	Bank.Parent = leaderstats

	-- Retrieve data
	local data
	local successful, errormessage = pcall(function()
		data = MoneyDataStore:GetAsync(plr.UserId)
	end)

	-- Set values of leaderstats after data loaded
	if successful then
		-- If data exists
		if data then
			Cash.Value = data["Cash"]
			Bank.Value = data["Bank"]
		end
		
	-- If data failed to load
	else
		Cash.Value = 100
		Bank.Value = 100
		warn(errormessage)
	end

	-- Parent leaderstats to player after data loaded
	leaderstats.Parent = plr
end



-- Save player data
local function saveData(plr)
	-- Get leaderstats data
	local Cash = plr:FindFirstChild("leaderstats").Cash
	local Bank = plr:FindFirstChild("leaderstats").Bank

	-- Save data
	local data = {
		["Bank"] = Bank.Value;
		["Cash"] = Cash.Value;
	}
	local successfull, errormessage = pcall(function()
		MoneyDataStore:SetAsync(plr.UserId, data)
	end)

	-- Prints
	if successfull then
		print("Data Saved Successfully")
	else
		print("Encountered An Error While Saving Data")
	end
end

-- Load / Save player data on join / leave
Players.PlayerAdded:Connect(loadData)
Players.PlayerRemoving:Connect(saveData)

-- Save all players' data when game closes
game:BindToClose(function()
	task.wait(1)
	for _, player in Players:GetPlayers() do
		task.spawn(function()
			saveData(player)
		end)
	end
end)

I would also try and incorporate @1pad_a1r 's solution as well. He has a loop that repeats data retrieval / save until success is returned, in case there is an error!

3 Likes

very sorry for the late response, so far its working but im wondering in the line

it kicks the player if his data couldnt load, what if the data just corrupted and never will load again, wouldnt that just make the player stuck in a kick loop basically banning them from the game?

Yeah but if any problem don’t make the data loaded for the player he will be mad or something, so we kick him and he should try again.