Data not saving

I have a script which saves the number of deaths, the time spent and the stages. My seconds and deaths values are not saving. I think has to do with something in the player added function where it instantly makes the deaths and seconds values 0 but make the stages value into obbyData.

code:

local died = false
local secondsHandler = false
local checkpoints = workspace.Checkpoints
local dss = game:GetService("DataStoreService")
local Datastore = dss:GetDataStore("ObbyData")
local Players = game:GetService("Players")
game:BindToClose(function()
	for _,Player in pairs(Players:GetPlayers())do
		Player:Kick("This server is shutting down")
	end
	wait(3)
end)
print("Checkpoints leaderstats working")
print("Deaths leaderstats working")
print("Time leaderstats working")
game.Players.PlayerAdded:Connect(function(plr)
	local obbyData = Datastore:GetAsync(plr.UserId .. "-obbyStageProgress")

	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = plr
	
	local stage = Instance.new("StringValue")
	stage.Name = "Stage"
	stage.Value = (obbyData and obbyData[1]) or 1
	stage.Parent = stats
	
	local wipeouts = Instance.new("IntValue")
	local wipeoutsData = Datastore:GetAsync(plr.UserId,wipeouts.Value)
	wipeouts.Name = "Deaths"
	wipeouts.Value =  wipeoutsData
	wipeouts.Parent = stats
	
	local second = Instance.new("IntValue")
	local secondData = Datastore:GetAsync(plr.UserId,second.Value)
	second.Name = "Seconds"
	second.Value = secondData
	second.Parent = stats

	

	local char = plr.Character or plr.CharacterAdded:Wait()
	char:WaitForChild("HumanoidRootPart").CFrame = checkpoints[stage.Value].CFrame
	
	char.Humanoid.Touched:Connect(function(touch)
		if touch.Parent == checkpoints then
			if (tonumber(touch.Name)and tonumber(touch.Name)>tonumber(stage.Value))or touch.Name == "End"then
				stage.Value = touch.Name
				
			end
		end
		
		plr.CharacterAdded:Connect(function(char)
			local hrp = char:WaitForChild("HumanoidRootPart")
			local humanoid = char:WaitForChild("Humanoid")
			hrp:GetPropertyChangedSignal("CFrame"):Wait()
					hrp.CFrame = checkpoints[stage.Value].CFrame
			humanoid.Died:Connect(function()
			if not died then
				died = true
				wipeouts.Value = wipeouts.Value + 1
                wait(5)
				died = false
			end
end)	
				
			
				
				local humanoid = char:WaitForChild("Humanoid")	
			humanoid.Touched:Connect(function(touch)
				if touch.Parent == checkpoints then
					if (tonumber(touch.Name)and tonumber(touch.Name)>tonumber(stage.Value))or touch.Name == "End" then
						stage.Value = touch.Name
						
					end
					
				end
			end)
			while true do
				wait()
				if not secondsHandler then
					secondsHandler = true
					second.Value = second.Value + 1
					wait(1)
					secondsHandler = false
						end	
				end
								
		end)
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local DatastoreTable = {
	player.leaderstats.Stage.Value,
	player.leaderstats.Deaths.Value,
	player.leaderstats.Seconds.Value
	}
	local success, fail = pcall(function()
		Datastore:SetAsync(player.UserId .. "-obbyStageProgress", DatastoreTable)
	end)
	if success then print(success) else print(fail) end
		end)
1 Like

There is a while true do loop in your script above the PlayerRemoving event, so that is probably looping infinitely so the script will never be able to get to the PlayerRemoving event.

1 Like

so where should I put it or what should I do as that is what makes my seconds value go up every second.

1 Like

You could make the script after the PlayerRemoving event which will increase everyone’s value every second (with a for i, v in pairs(players:GetChildren()) script)

3 Likes

Could you write me the script part . This is what I put but it doesn’t work.

for i, v in pairs(Players:GetChildren()) do
	wait(1)
	v.leaderstats.Seconds.Value = 	v.leaderstats.Seconds.Value + 1
end

It has to be wrapped in a while loop so that it repeats infinitely. And there shouldn’t be a wait between iterations in the getchildren() table

1 Like
while true do
    for _,player in pairs(Players:GetPlayers()) do
        wait(1)
        player.leaderstats.Seconds.Value = v.leaderstats.Seconds.Value + 1
    end
end
1 Like

My data is still not saving.
code:

local died = false
local secondsHandler = false
local checkpoints = workspace.Checkpoints
local dss = game:GetService("DataStoreService")
local Datastore = dss:GetDataStore("ObbyData")
local Players = game:GetService("Players")
game:BindToClose(function()
	for _,Player in pairs(Players:GetPlayers())do
		Player:Kick("This server is shutting down")
	end
	wait(3)
end)
print("Checkpoints leaderstats working")
print("Deaths leaderstats working")
print("Time leaderstats working")
game.Players.PlayerAdded:Connect(function(plr)
	local obbyData = Datastore:GetAsync(plr.UserId .. "-obbyStageProgress")

	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = plr
	
	local stage = Instance.new("StringValue")
	stage.Name = "Stage"
	stage.Value = (obbyData and obbyData[1]) or 1
	stage.Parent = stats
	
	local wipeouts = Instance.new("IntValue")
	local wipeoutsData = Datastore:GetAsync(plr.UserId,wipeouts.Value)
	wipeouts.Name = "Deaths"
	wipeouts.Value =  wipeoutsData
	wipeouts.Parent = stats
	
	local second = Instance.new("IntValue")
	local secondData = Datastore:GetAsync(plr.UserId,second.Value)
	second.Name = "Seconds"
	second.Value = secondData
	second.Parent = stats

	

	local char = plr.Character or plr.CharacterAdded:Wait()
	char:WaitForChild("HumanoidRootPart").CFrame = checkpoints[stage.Value].CFrame
	
	char.Humanoid.Touched:Connect(function(touch)
		if touch.Parent == checkpoints then
			if (tonumber(touch.Name)and tonumber(touch.Name)>tonumber(stage.Value))or touch.Name == "End"then
				stage.Value = touch.Name
				
			end
		end
		
		plr.CharacterAdded:Connect(function(char)
			local hrp = char:WaitForChild("HumanoidRootPart")
			local humanoid = char:WaitForChild("Humanoid")
			hrp:GetPropertyChangedSignal("CFrame"):Wait()
					hrp.CFrame = checkpoints[stage.Value].CFrame
			humanoid.Died:Connect(function()
			if not died then
				died = true
				wipeouts.Value = wipeouts.Value + 1
                wait(5)
				died = false
			end
end)	
				
			
				
				local humanoid = char:WaitForChild("Humanoid")	
			humanoid.Touched:Connect(function(touch)
				if touch.Parent == checkpoints then
					if (tonumber(touch.Name)and tonumber(touch.Name)>tonumber(stage.Value))or touch.Name == "End" then
						stage.Value = touch.Name
						
					end
					
				end
			end)
			
								
		end)
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local DatastoreTable = {
	player.leaderstats.Stage.Value,
	player.leaderstats.Deaths.Value,
	player.leaderstats.Seconds.Value
	}
	local success, fail = pcall(function()
		Datastore:SetAsync(player.UserId .. "-obbyStageProgress", DatastoreTable)
	end)
	if success then print(success) else print(fail) end
end)

while true do
	wait()
    for _,player in pairs(Players:GetPlayers()) do
        wait(1)
        player.leaderstats.Seconds.Value = player.leaderstats.Seconds.Value + 1
    end
end

Try using JSONncode and JSONdecode on your table of values to save and load data since you can’t save tables like that as a Value in a data store. Typing on mobile so I can’t really give code samples.

Sorry but I do not understand the JSONncode and do not know how I will put it in my code. A code sample would be helpful from someone else.

JSONEncode turns a table into a string meaning the DataStoreService can save it , That in mind when the player join you Decode the string by using JSONDecode, They’re both functions of HttpService, Hope this helped.

JSONEncode: HttpService | Documentation - Roblox Creator Hub
JSONDecode: HttpService | Documentation - Roblox Creator Hub

1 Like

Can i have a code sample from the problem in script above? It will be heplful.

Sure thing let me make something really quick.

1 Like

Here you go look at this script and understand the use of HttpService, the game needs to have Http requests on and API on and needs to be public for this to work, Hope this helped.

Script:

local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetDataStore("Dev Forum Help2")
local HttpService = game:GetService("HttpService")


game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player
	
	local stage = Instance.new("StringValue")
	stage.Name = "Stage"
	stage.Value = 0
	stage.Parent = stats
	
	local wipeouts = Instance.new("IntValue")
	
	wipeouts.Name = "Deaths"
	wipeouts.Value = 0
	wipeouts.Parent = stats
	
	local second = Instance.new("IntValue")

	second.Name = "Seconds"
	second.Value = 0
	second.Parent = stats
	local data
	local success, errormessage = pcall(function()
		data = DataStore:GetAsync(player.UserId.."-DataStore")
		if data then
			local newData = HttpService:JSONDecode(data)
			stage.Value = newData[1]
			wipeouts.Value = newData[2]
			second.Value = newData[3]
		end
	end)

	if success then 
		print("Loaded")
	end
	
	if not success then
		print(errormessage)
	end
end)


game:BindToClose(function()
	local player 
	local c = game.Players:GetPlayers()
	for i = 1,#c do
   		 player = c[i]
	end
	local success, errormessage = pcall(function()
			local Data = {
				player.leaderstats.Stage.Value;	
				player.leaderstats.Deaths.Value;
				player.leaderstats.Seconds.Value;
			}
			
			local newdata = HttpService:JSONEncode(Data)
		
			DataStore:SetAsync(player.UserId.."-DataStore",newdata)
		end)
	if success then 
		print("Saved")
	elseif errormessage then
		print(errormessage)
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
				local Data = {
				player.leaderstats.Stage.Value;	
				player.leaderstats.Deaths.Value;
				player.leaderstats.Seconds.Value;
			}
		
		local newdata = HttpService:JSONEncode(Data)
		DataStore:SetAsync(player.UserId.."-DataStore",newdata)
	end)
	if success then 
		print("Saved")
	elseif errormessage then
		print(errormessage)
	end
end)
1 Like

Change the value from another script that detects death or checkpoints and a while loop for seconds, my script only saves the data it.

How do i access the datastore and values from those scripts

You dont need to, You just get the values from the leaderstats folder and change the value, as i said my script does not change any values only saves them,

Example:

game.Players.PlayerAdded:Connect(function(Player)
    while wait(1) do
          Player.leaderstats.Seconds.Value = Player.leaderstats.Seconds.Value + 1
    end
end)
1 Like