Problem with datastore

Hello fellow developers! I’m having a problem with my datastore.

image
When I click and stuff it works, but when I leave it doesn’t save even though it says it does
image
Then it doesn’t save
image

Here’s my script

local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("DataStore")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Clicks = Instance.new("NumberValue")
	Clicks.Name = "Clicks"
	Clicks.Parent = leaderstats
	
	local Rebirths = Instance.new("NumberValue")
	Rebirths.Name = "Rebirths"
	Rebirths.Parent = leaderstats	
	
	local data
	local success, errormessage = pcall(function()
		data = DataStore:GetAsync(player.UserId.."-clicks", player.UserId.."-rebirths")
	end)
	
	if success then
		Clicks.Value = data
		Rebirths.Value = data
	else
		print("There was an error")
		warn(errormessage)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local success, errormessage = pcall(function()
		DataStore:SetAsync(player.UserId.."-clicks", player.leaderstats.Clicks.Value)
		DataStore:SetAsync(player.UserId.."-rebirths", player.leaderstats.Rebirths.Value)
	end)
	if success then
		print("Players data has been saved")
	else
		print("Players data is errored")
		warn(errormessage)
	end
end)

The error here is how you are getting the values, in this line below.

data = DataStore:GetAsync(player.UserId…“-clicks”, player.UserId…“-rebirths”)

Here’s how you would implement it if you want them both in a table / the same value.

data = {}
table.insert(data, DataStore:GetAsync(player.UserId.."-clicks"))
table.insert(data, DataStore:GetAsync(player.UserId.."-rebirths"))

If you were to implement it the way I did above you would also have to change the success updating’s like so.

Clicks.Value = data[1]
Rebirths.Value = data[2]

you could reduce the number of :GetAsync calls by saving the data as a table.

I took the reduced :GetAsync calls into account while I was writing my reply, but I’m assuming that his game is already released and may have previously saved data. Though if it isnt released, saving it as a table would be a better option.

oh ok fair enough i guess… . . . … . . … . .

Still doesn’t seem to be working, it may be because I’m in studio though

Edit: noticed that every other time it will print “Players data has saved”, other times it won’t print anything

Make sure you have Enable Studio Access to API Services enabled in the game settings so you can access data stores.
Also, adding on to what undiscvrd said earlier,

you should also have data1 and data2, or replace their names for clicks and rebirths, like this

local clicks
local rebirths

then change

data = DataStore:GetAsync(player.UserId.."-clicks", player.UserId.."-rebirths")

into

clicks = DataStore:GetAsync(player.UserId.."-clicks")
rebirths = DataStore:GetAsync(player.UserId.."-rebirths")

Also change

if success then
	Clicks.Value = data
	Rebirths.Value = data
else
	print("There was an error")
	warn(errormessage)
end

into

if success then
	Clicks.Value = clicks
	Rebirths.Value = rebirths
else
	print("There was an error")
	warn(errormessage)
end

Still the same thing is happening, and I do have API services enabled

1 Like

Can you send the new script with the changes?

local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("DataStore")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Clicks = Instance.new("NumberValue")
	Clicks.Name = "Clicks"
	Clicks.Parent = leaderstats
	
	local Rebirths = Instance.new("NumberValue")
	Rebirths.Name = "Rebirths"
	Rebirths.Parent = leaderstats	
	
	local clicks = nil
	local rebirths = nil
	local success, errormessage = pcall(function()
		clicks = DataStore:GetAsync(player.UserId.."-clicks")
		rebirths = DataStore:GetAsync(player.UserId.."-rebirths")
	end)
	
	if success then
		Clicks.Value = clicks
		Rebirths.Value = rebirths
	else
		print("There was an error")
		warn(errormessage)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local success, errormessage = pcall(function()
		DataStore:SetAsync(player.UserId.."-clicks", player.leaderstats.Clicks.Value)
		DataStore:SetAsync(player.UserId.."-rebirths", player.leaderstats.Rebirths.Value)
	end)
	if success then
		print("Players data has been saved")
	else
		print("Players data is errored")
		warn(errormessage)
	end
end)

Make sure that the values for the Rebirths and Clicks are changed from the serverside and not the clientside because otherwise the data won’t be saved

So would serverscriptservice work?

Yes, clicks need to be fired from a remote event to the server, you can also validate the clicks there eventually, then change the leaderstats value from a script preferably in the serverscriptservice. Same thing with the rebirths. Never rely on the client for data validation.

tl;dr the scripts usually should be in server script service

image
So something like this wouldnt work?

code inside local script:

local debounce = false
local debouncetime = .1

script.Parent.MouseButton1Click:Connect(function()
	if not debounce then
		debounce = true
		local player = game.Players.LocalPlayer
		local clicks = player:WaitForChild("leaderstats"):WaitForChild("Clicks")
		local rebirths = player:WaitForChild("leaderstats"):WaitForChild("Rebirths")
		local amount = script.Parent.Amount
		local Multiplier = script.Parent.Multiplier

		script.Parent:TweenSize(UDim2.new(0, 117,0, 118), Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, .01)
		wait(.02)
		script.Parent:TweenSize(UDim2.new(0, 130,0, 131), Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, .01)

		clicks.Value += amount.Value + rebirths.Value
		wait(debouncetime)
		debounce = false
	end
end)

No that wouldn’t work because even though the data is being changed on the client, other players and the server, won’t see that data. So you should have a RemoteEvent or, better yet, a RemoteFunction

If you don’t know what those are, they just send signals to the server or client so they can process the data. They can do server → client and client → server. RemoteFunctions also send a signal, but they require a response using return

Also, data that is verified on the client is easily exploited. That’s why a script that validates the data serverside is so much safer.

Alright, thanks I’ll check both of these out

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.