Datastore Not Saving

Here is my ENTIRE script:

local DS = game:GetService("DataStoreService")
local data
local PointsStore = DS:GetDataStore("Points")
local playerStats = {}
group = script.GroupID.Value
default = script.DefaultRank.Value

game.Players.PlayerAdded:connect(function(player)
	local leaderstats = Instance.new("Model", player)
	leaderstats.Name = "leaderstats"
	local grouprank = Instance.new("StringValue", leaderstats)
	grouprank.Name = "Rank"
	local rank = player:GetRoleInGroup(group)
	if rank ~= "Guest" then
		grouprank.Value = rank
	else
		grouprank.Value = default
	end

	local points = Instance.new("IntValue", leaderstats)
	points.Name = "Points"
	if points ~= 0 then
		points.Value = 0
	end
	playerStats[player] = leaderstats

	local success, Error = pcall(function()
		data = PointsStore:GetAsync(player.UserId.."-Points")
	end)
	
	if success then
		points.Value = data
	else
		warn(Error)
	end
end)

Ok…so where do you save the data?

I mean you use UpdateAsync or SetAsync to save data to the datastore. If you’re having a problem with saving data then is it in the saving or is it in the loading? Have you already isolated it to loading?

1 Like

Try using if points.Value ~= 0 then because it looks like you didn’t define the variable. Could be wrong. Also test it out in your own place and not a group game as others have stated.

1 Like

I added this line to my code:

points.Changed:Connect(function()
		PointsStore:SetAsync(player.UserId, points.Value)
	end)

I tried changing the value via explorer and then I ended the test and then I re-loaded and it was 0 again.

I will try now to put it on a game on my profile and not a group.

that is bad practice datastores should be auto saved and when the player leaves if you dont want this complexity then use DataStore2

1 Like

You’re using 2 separate Keys there!

Here you’re setting the points under the Player’s UserId

while in the original script:

You get the points from UserID…“-Points”


Say my userId is 0

Your script gets “0-Points”
then it sets my points value to “0”

They are 2 separate keys!!! They go to different things! To the datastore those are 2 completely separate entities.

1 Like

So remove this? 30Chars30Chars30Chars

That would work if you want to do that. Just remember it has to be the same key

Still not working, I have it on a profile game, I did everything… Here is my script now:

local DS = game:GetService("DataStoreService")
local data
local PointsStore = DS:GetDataStore("Points")
local playerStats = {}
group = script.GroupID.Value
default = script.DefaultRank.Value

game.Players.PlayerAdded:connect(function(player)
	local leaderstats = Instance.new("Model", player)
	leaderstats.Name = "leaderstats"
	local grouprank = Instance.new("StringValue", leaderstats)
	grouprank.Name = "Rank"
	local rank = player:GetRoleInGroup(group)
	if rank ~= "Guest" then
		grouprank.Value = rank
	else
		grouprank.Value = default
	end

	local points = Instance.new("IntValue", leaderstats)
	points.Name = "Points"
	if points.Value ~= 0 then
		points.Value = 0
	end
	playerStats[player] = leaderstats

	local success, Error = pcall(function()
		data = PointsStore:GetAsync(player.UserId)
	end)
	
	if success then
		points.Value = data
	else
		warn(Error)
	end
	points.Changed:Connect(function()
		PointsStore:SetAsync(player.UserId, points.Value)
	end)
end)

This part is unecessary. I’d get rid of it as it’s just clutter.


Make sure to check if data even exists while you’re checking if it was successful. It can still return successful even if it’s nil!


just move this into PlayerAdded there’s no reason to keep it at the top of the script.


Just thought you should know that this is very unsafe don’t keep this as a permanent solution


Make sure this is in a server script and when you’re changing your point values you’re on the server, not the client.

1 Like

I already did this:

Moved.

How do I make it safer?

It is, its in ServerScriptService.

As I said before that’s not useful in the slightest.

I’m talking about here. You should be checking if success and data then as it may still be successful but nil. (That’s if the request went through but there was no data)
Your line of code there is checking if a newly created IntValue isn’t 0 then set it to 0. What’s the problem? All IntValues are by default set to 0. You’re not even checking the data there. You only even make the request later in the script making it completely useless.


Well you could connect the function to when your player leaves. When the player leaves is probably the best time to save all of the data. You could also add checks to see if the data properly loaded. This way you don’t save data that shouldn’t exist.


Well that seems good. I’m not sure other than change the value from the server. It should be saving after all of the precautions. If not then try manually saving something to the datastore and playing. If it doesn’t show up then at least we know it’s the loading part that’s broken not the saving part.

1 Like

How would I do this though? I am at a Intermediate level.

change that
to:

if success and data then
		points.Value = data
	else
		warn(Error) -- This will fire everytime a new player joins and/or there isn't data so maybe remove this or make it a separate check
	end

Also was it the saving part or the loading part? How did your experiment with manually saving go?

1 Like

I am not getting any errors in the console so I don’t know how to check. Its just not saving still, even after doing what you said. Current Script:

local DS = game:GetService("DataStoreService")
local PointsStore = DS:GetDataStore("Points")
local playerStats = {}
group = script.GroupID.Value
default = script.DefaultRank.Value

game.Players.PlayerAdded:connect(function(player)
	local leaderstats = Instance.new("Model", player)
	leaderstats.Name = "leaderstats"
	local grouprank = Instance.new("StringValue", leaderstats)
	grouprank.Name = "Rank"
	local rank = player:GetRoleInGroup(group)
	if rank ~= "Guest" then
		grouprank.Value = rank
	else
		grouprank.Value = default
	end

	local points = Instance.new("IntValue", leaderstats)
	points.Name = "Points"
	playerStats[player] = leaderstats
	
	local data
	local success, Error = pcall(function()
		data = PointsStore:GetAsync(player.UserId)
	end)
	
	if success and data then
		points.Value = data
	else
		warn(Error)
	end
	points.Changed:Connect(function()
		PointsStore:SetAsync(player.UserId, points.Value)
	end)
end)

Is it not saving or is it not loading? Again - how did manually saving a value like say 100 via the command line go? (not editing a value)

1 Like

I have a TextButton that you press and it adds a point, it adds a point.

I don’t know. There are no errors. How would I check this?

Remove

	points.Changed:Connect(function()
		PointsStore:SetAsync(player.UserId, points.Value)
	end)

and add this at the end of the script

-- check if a player left
game.Players.PlayerRemoving:Connect(function(plr)
   -- define data
   local data
   -- to prevent errors or fails if datastoreervice is down or not
   local success,err = pcall(function()
    -- ser the async so we could get it back when he joins again
    data = DataStore:SetAsync(plr.UserId.."-Points", plr.points.Value)
   end)
   -- check if it saved or not if not its gonna print an error
   if s then print("Successfully saved") else error("Datastore error:: "..e) end
end)

and at datastore:getasync change it to this

DataStore:GetAsync(plr.UserId.."-Points")

and it should work fine

check out @megatank58’s solution too.

3 Likes

The text button is probably working local so it doesn’t replicates and the server doesn’t knows about it you should use a Remote event to communicate between client and server and save the value from server side ONLY

2 Likes