Why is my datastore not saving?

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

local ds = dss:GetDataStore("dwjkadlkwajwdjlska")
local RUnService = game:GetService("RunService")
players.PlayerAdded:Connect(function(plr)
	
	local userID = plr.UserId
	local key = "plr_" ..userID
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	
	local Clicks = Instance.new("IntValue")
	Clicks.Value = 0
	Clicks.Name = "Clicks"
	Clicks.Parent = leaderstats
	
	local Gems = Instance.new("IntValue")
	Gems.Value = 0
	Gems.Name = "Gems"
	Gems.Parent = leaderstats
	
	local Rebirths = Instance.new("IntValue")
	Rebirths.Name = "Rebirths"
	Rebirths.Value = 0
	Rebirths.Parent = leaderstats
	
	local sucess, returnValue
	sucess, returnValue = pcall(ds.GetAsync, ds, key)
	print(returnValue)
	
	if sucess then
		if returnValue == nil then
			returnValue = {
				Clicks = 0,
				Gems = 0,
				Rebirths = 0,
			}
		end
		
		print(returnValue)
		Rebirths.Value = if returnValue.Rebirths ~= nil then returnValue.Rebirths else 0
		Gems.Value = if returnValue.Gems ~= nil then returnValue.Gems else 0
		Clicks.Value = if returnValue.Clicks ~= nil then returnValue.Clicks else 0
		
	else
		plr:Kick("Your data couldn't load. Please rejoin or contact us in our group Toolbox Z Studios.")
		print(plr.Name.. " had trouble loading their data.")
	end
end)

local function save(plr)
	local userID = plr.UserId
	local key = "plr_" ..userID
	
	local Gems = plr.leaderstats.Gems.Value
	local Clicks = plr.leaderstats.Clicks.Value
	local Rebirths = plr.leaderstats.Rebirths.Value
	
	local dataTable = {
		Gems = Gems,
		Clicks = Clicks,
		Rebirths = Rebirths,
	}
	
	print(dataTable)
	
	local success, returnValue 
	success, returnValue = pcall(ds.UpdateAsync, ds, key, function()
		return dataTable
	end)
	
	if success then
		print("DataSaved")
	else
		print("DataSavingError")
	end
end

local function onShutDown()
	if RUnService:IsStudio() then
		task.wait(2)
	else
		local finished = Instance.new("BindableEvent")
		local allPlayers = players:GetPlayers()
		local leftPlayers = #allPlayers
		
		for _, player in ipairs(allPlayers) do
			coroutine.wrap(function()
				save(player)
				leftPlayers -= 1
				if leftPlayers == 0 then
					finished:Fire()
				end
			end)()
		end
		finished.Event:Wait()
	end
end

game:BindToClose(onShutDown)
players.PlayerRemoving:Connect(save)

Context: When I leave the game it says in the output (printed, along the lines of) “Data Store Saved” and when I rejoin it doesn’t load my data.

2 Likes

what is the return value printing on join?

2 Likes
["Clicks"] = 0,
["Gems"] = 0,
["Rebirths"] = 0

I believe the problem is it’s saving the values as 0 when I leave but idk how to fix it.

Try this:

local function save(plr)
	local userID = plr.UserId
	local key = "plr_" ..userID
	
	local Gems = plr.leaderstats.Gems
	local Clicks = plr.leaderstats.Clicks
	local Rebirths = plr.leaderstats.Rebirths
	
	local dataTable = {
		Gems = Gems.Value,
		Clicks = Clicks.Value,
		Rebirths = Rebirths.Value,
	}
	
	print(dataTable)
	
	local success, returnValue 
	success, returnValue = pcall(ds.UpdateAsync, ds, key, function()
		return dataTable
	end)
	
	if success then
		print("DataSaved")
	else
		print("DataSavingError")
	end
end

Still not saving, right when I leave the output tells me what value it saved, and it said 0 for all (clicks, rebirths, gems.)

How are you changing the values? Any changes from client side are not made to the server so the data will still be set as 0.

Not sure what that means, but the script is in server script service.

What I mean is how are you changing clicks, gems, rebirths. Through a localscript/console? Or from a server script?

For example, if you click the screen a local script might detect that and change the value but that changed value is not replicated to the server for security reasons.

I just realized, this is being changed client sided. That’s why when other people play they can’t see the other persons value. How do I change it to server side?

P.S I’m not using a local script I’m using regular script

Use a ReplicatedEvent & a serverscript inside ServerScriptService then fire the event from the client to tell the server to change the value.

How would I do that? (pls spoon feed me. jk but I dont know how to do that)

  1. Where do I put the event?
  2. What type of event do I use?
  3. Do I fire it in the same script above?

@spoopmoop

  1. Typically people put remote events in ReplicatedStorage.
  2. I accidentally refered to it as ReplicatedEvent but it’s Remote Event.
  3. You would fire the event in the local scripts where you are detecting clicks, etc. and you would fire the remote event using RemoteEvent:FireServer() then on server script you would use RemoteEvent.OnServerEvent and you would connect a function that adds to the players click count.

The script in OP is a server script, so what local script are you talking about?

so I would do

RemoteEvent.OnServerEvent:Connect(function(plr)
      plr.leaderstats.Gems.Value = plr.leaderstats.Gems.Value + (amount here)
end)

or am I doing something wrong

Oh I know what you mean now but would my game crash if each player keeps sending a remote event? Like would it not work if I send a remote event each time that someone clicks

Edit: also how do I sent the value of the amount of clicks a person clicked on a remote event! For example if someone can get 10 clicks each time they click (Ik sounds dumb lol) the remote event would tell the server script they should add 10 value to the click @spoopmoop

The scripts I am referring to are the ones you were talking about here ^

You could alternatively place the remote event and server script inside StarterGui so each player has their own event.

I would recommend saving an int value with the multiplier and then use that multiplier to calculate how many clicks they should get. Passing in an amount variable could be used by scripters to get an inf amount of clicks instantly.

Rebirths.Value = if returnValue.Rebirths ~= nil then returnValue.Rebirths else 0
Gems.Value = if returnValue.Gems ~= nil then returnValue.Gems else 0
Clicks.Value = if returnValue.Clicks ~= nil then returnValue.Clicks else 0
Rebirths.Value = returnValue.Rebirths or 0
Gems.Value = returnValue.Gems or 0
Clicks.Value = returnValue.Clicks or 0

The output said

 Remote event invocation queue exhausted for Players.MRG_GROUPHOLDER.PlayerGui.Clicker.Frame.RemoteEvent; did you forget to implement OnServerEvent? (4 events dropped)