Always having issues with Datastore

I’m making a game and, like most games, need Datastore. This has always been a problem for me, I know about Datastore and have tried making systems that avoid dataloss, but for a while now I can even seem to get a basic Datastore system to work. Simply said, it wipes my data every time I test the game.
Enable Studio Access to API Services is on.
This is the script that handles datastore:

local DatastoreService = game:GetService('DataStoreService')
local ServerStorage = game:GetService('ServerStorage')

local Datastore = DatastoreService:GetDataStore('Bizarre_Yoyo-1')

game.Players.PlayerAdded:Connect(function(Player)
	local success, data = pcall(function()
		Datastore:GetAsync(Player.UserId)
	end)
	if not success then
		Player:Kick('Error when Loading Data, please try again')
	end
	
	print(data)
	
	if data == nil then
		data = 'Broken Yoyo|0'
		local success, err = pcall(function()
			Datastore:SetAsync(Player.UserId,'Broken Yoyo|0')
		end)
	end
	
	ServerStorage.PlayerData:FindFirstChild(Player.Name).YoyoUsage.Value = string.split(data,'|')[2]
	ServerStorage.PlayerData:FindFirstChild(Player.Name).Yoyo.Value = ServerStorage:FindFirstChild(string.split(data,'|')[1])
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local saveString = ServerStorage.PlayerData:FindFirstChild(Player.Name).Yoyo.Value.Name..'|'.. tostring(ServerStorage.PlayerData:FindFirstChild(Player.Name).YoyoUsage.Value)
	local success, err = pcall(function()
		Datastore:SetAsync(Player.UserId,saveString)
	end)
	if not success then
		warn(err)
	end
end)

game.Close:Connect(function()
	for _,Player in pairs(game.Players:GetChildren()) do
		local saveString = ServerStorage.PlayerData:FindFirstChild(Player.Name).Yoyo.Value.Name..'|'.. tostring(ServerStorage.PlayerData:FindFirstChild(Player.Name).YoyoUsage.Value)
		local success, err = pcall(function()
			Datastore:SetAsync(Player.UserId,saveString)
		end)
	end
end)

while true do
	wait(300)
	for _,Player in pairs(game.Players:GetChildren()) do
		local saveString = ServerStorage.PlayerData:FindFirstChild(Player.Name).Yoyo.Value.Name..'|'.. tostring(ServerStorage.PlayerData:FindFirstChild(Player.Name).YoyoUsage.Value)
		local success, err = pcall(function()
			Datastore:SetAsync(Player.UserId,saveString)
		end)
	end
end
1 Like

I would say to avoid Dataloss go use DataStore2, it is way better and it prevents DataLoss.

It also could be because, you’re testing it in studio.

I tried testing it out of studio too, still didn’t work, and I’m not sure how to set up Datastore2

Instead of game.Close try BindToClose. I don’t even know game.Close exist until now.

The issue isn’t with game.Close, I have a game.Players.PlayerRemoving Event which should save data too, but doesn’t. and I found game.Close on the official roblox lua documentation.

game.Close and BindToClose’s relation is the same as RunService.RenderStepped and RunService:BindToRenderStep

Here is DataStore Example. Note: edit the name of the DataStore and other things.
Code:

local DataStoreService = game:GetService("DataStoreService")
    local MinutesPlayedDataStore = DataStoreService:GetDataStore("MinutesPlayed")

    game.Players.PlayerAdded:Connect(function(player)
    	local leaderstats = Instance.new("Folder")
    	leaderstats.Name = "leaderstats"
    	leaderstats.Parent = player

    	local MinutesPlayedInt = Instance.new("IntValue")
    	MinutesPlayedInt.Name = "Minutes Played"
    	MinutesPlayedInt.Parent = leaderstats

    	local data
    	local success, errormessage = pcall(function()
    		data = MinutesPlayedDataStore:GetAsync(player.UserId.."-minutes played")
    	end)

    	if success then
    		MinutesPlayedInt.Value = data
    	else
    		print("There was an error while getting "..player.Name.." data!")
    		warn(errormessage)
    	end
    end)

    game.Players.PlayerRemoving:Connect(function(player)
    	local success, errormessage = pcall(function()
    		MinutesPlayedDataStore:SetAsync(player.UserId.."-minutes played", player.leaderstats["Minutes Played"].Value)
    	end)

    	if success then
    		print(player.Name.." data saved!")
    	else
    		print("There was an error while saving "..player.Name.." data!")
    		warn(errormessage)
    	end
    end)
1 Like

One quick change you could do is:

To this:

Datastore:SetAsync(Player.UserId, data)

( Since you already redefined the data to equal “Broken Yoyo|0” )

Also, you should be testing this in your official game. Testing in studio tends to bug out sometimes when it comes to DataStore.

1 Like

Thanks a lot! I still don’t know what went wrong, but it works now!

Since you are the only one in the server when you’re testing so when you leave, the game will just close so PlayerRemoving can’t run, that’s where BindToClose come in, it will give the game 30s to do stuff before shut down the server.

1 Like

I know I’m late on a response, but I’m answering anyway.

I think you are absolutely right! What I noticed even after I got it to work, is that when I stopped the game in studio, it wouldn’t always save. This is all speculation, but I believe what is happening is exactly what you explain. The game doesn’t have time to save when I close it down directly, but this doesn’t seem to be an issue when saving data in the actual game, as roblox takes a bit of time before it shuts down the server. In the future though, I will make sure I use BindToClose as it avoids a lot of issues.