Script stops working

My seconds’ value was going up but now it says seconds is not a valid member of folder (leaderstats). Also, my data seems to not be saving.

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

Don’t do this like this. When Player joins, it immediately calls this. But oh no, the Data are not loaded yet!

Do this while-loop at the end of the PlayerAdded block.

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

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

But the while true loop is in the player remove function. And I do not see a difference with the while true do loop and mine.

Sorry! I have put it in the wrong event. Put the while-loop into PlayerAdded event!

but that make any code after it stop as it is an infinite loop

Well yes. But it is sure that all data is loaded. You could possibly just have some variable which you would set to true, after their data is loaded and then just do:

while DataLoaded do
wait(1)
--do your stuff

I am sorry but how do i do that. I know how to do the true stuff but how do i know when the data has loaded. Also, wouldn’t the data not save as the code that saves it is after.

Basically something like this:

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")
local DataLoaded = {}
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

        DataLoaded[Player.Name] = true	

	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
     if DataLoaded[Player.Name] then
         player.leaderstats.Seconds.Value = player.leaderstats.Seconds.Value + 1
     end
        wait(1)
    end
end
1 Like

I tried it but the data does not save. I think that it something to do with how the deaths value equals the data (same with seconds). I think there is an error with that.

the part:

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

You are getting Async, not setting! The one and only arguments should be the key!
Same goes for other GetAsyncs

like this:


	local wipeouts = Instance.new("IntValue")
	local wipeoutsData = Datastore:GetAsync(plr.UserId .. "DeathsData")
	wipeouts.Name = "Deaths"
	wipeouts.Value =  wipeoutsData
	wipeouts.Parent = stats
	
	local second = Instance.new("IntValue")
	local secondData = Datastore:GetAsync(plr.UserId .. "SecondsData")
	second.Name = "Seconds"
	second.Value = secondData
	second.Parent = stats
1 Like

My data still doesn’t save

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")
local DataLoaded = {}
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 secondData = Datastore:GetAsync(plr.UserId .. "-SecondsData")
	local wipeoutsData = Datastore:GetAsync(plr.UserId .. "-DeathsData")
	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")
	
	wipeouts.Name = "Deaths"
	wipeouts.Value = wipeoutsData
	wipeouts.Parent = stats
	
	local second = Instance.new("IntValue")

	second.Name = "Seconds"
	second.Value = secondData 
	second.Parent = stats

        DataLoaded[plr.Name] = true	

	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
     if DataLoaded[player.Name] then
         player.leaderstats.Seconds.Value = player.leaderstats.Seconds.Value + 1
     end
        wait(1)
    end
end