Help with Datastore

So I have made a plot Save/Load system that saves and loads a builders creations. However when they clear there plot saved using :RemoveAsync(There UserID) and then build something new, that new data doesn’t get saved.

There Data is save using :SetAsync(There UserID) and loaded using :GetAsync(There UserID).

If the player then rejoins without there data saving and they build something new, it saves fine, only when they Remove there data does it not save.

I print the values that gets saved when they leave and they are there it just seems that the data isn’t actually saved to there key.

The reason why I am confused is that when they leave there data is set again yet isn’t there when the load?

Any help/explanation would be appreciated!

Could please post the relevant parts of your script?

1 Like

Yes, could you please clarify.

Also, my head hurts after reading that.

game:GetService("DataStoreService"):SetAsync(Player.UserId, {}) -- The table can hold data that will save!

How are you storing the data, in tables or as indexes in the Datastore?

Are you adding extra indexes into a players datastore?

You can’t have a player with a different number of indexes to another player. Datastores are databases, which means that every record must contain the same number of keys otherwise data can skew into/over other records. This can cause a failure to save because of the size difference to their own record or other players records.

Are you testing this in Studio if so you should use the :BindToClose event to save data as it executes everything of the function a few seconds before the server shuts down

https://developer.roblox.com/en-us/api-reference/function/DataModel/BindToClose

1 Like

Unfortunately, Datastore:RemoveAsync() doesn’t work at all for some reason. Use

Datastore:UpdateAsync(UserID,function()
return {} -- Saving an empty table
end)-- How you should use Datastore:UpdateAsync()

And don’t use Datastore:SetAsync() when saving important data as it overwrites existing data (thus making it easier to reach the datastore limit and experience data loss.) instead of transforming the existing data. Use Datastore:UpdateAsync(). It works like this:

local success = pcall(function()
Datastore:UpdateAsync(UserId,function()
return {} --data to save
end) --transform function
end)

:RemoveAsync() works fine for me.

It never worked for me, although it might have worked for you in the past.

I’ve been using it today in relation to some DataStore testing, works perfectly fine.

That’s odd, it never worked with me before, even when I provided the UserId of the player. Even EgoMoose said it didn’t work for him.

It could be updated code, Roblox do supply a lot of updates. Never really had a problem with either method, only with the type/size/construct or differences in the data being used in SetSync() or UpdateSync().

So sorry for the confusion everyone, I didn’t have access to my computer at the time. Hopefully this should clarify:

local DataStoreService = game:GetService("DataStoreService")
local PlayerPlotData = DataStoreService:GetDataStore("TestDatastore")

local function OnPlayerJoin(player)

	local PlayerUserId = player.UserId
	local Data = PlayerPlotData:GetAsync(PlayerUserId)

	if Data then
		--Load Data.
	end
end


local function CreateTable(player)

	local PlayerPlotSave = {}

	for i, v in pairs(workspace.Model) do
		--Get each part.
	end

	return PlayerPlotSave
end


local function OnPlayerExit(player)

	local PlayerPlotSave = CreateTable(player)
	
	local success, err = pcall(function()
		
		local PlayerUserId = player.UserId
		PlayerPlotData:SetAsync(PlayerUserId, PlayerPlotSave) 
	end)

	if not success then

		warn('Could not save data!')
	end
end

game.Players.PlayerAdded:Connect(OnPlayerJoin)
game.Players.PlayerRemoving:Connect(OnPlayerExit)

I changed my code to this:

local DataStoreService = game:GetService("DataStoreService")
local PlayerPlotData = DataStoreService:GetDataStore("TestDatastore")

local function OnPlayerJoin(player)

	local PlayerUserId = player.UserId
	local Data = PlayerPlotData:GetAsync(PlayerUserId)

	if Data then
		--Load Data.
	end
end


local function CreateTable(player)

	local PlayerPlotSave = {}

	for i, v in pairs(workspace.Model) do
		--Get each part.
	end

	return PlayerPlotSave
end


local function OnPlayerExit(player)

	local PlayerPlotSave = CreateTable(player)
	
	local success, err = pcall(function()
		
		local PlayerUserId = player.UserId
		PlayerPlotData:SetAsync(PlayerUserId, PlayerPlotSave) 
	end)

	if not success then

		warn('Could not save data!')
	end
end

local function OnServerShutdown()
	for i, v in pairs(game.Players:GetChildren()) do
		--Save there data.
	end
end


game.Players.PlayerAdded:Connect(OnPlayerJoin)
game.Players.PlayerRemoving:Connect(OnPlayerExit)
game:BindToClose(OnServerShutdown)

And it seems to be functioning as intended!

1 Like