Help with script only working a random percent of the time

This is my first time scripting on Roblox and I have a script that tracks and saves how many studs a player walked. For some reason, it sometimes works and sometimes doesn’t. I have run the program many times and I can’t seem to find a pattern. Upon joining the game, there is a chance it tracks steps/points correctly and the rest of the time, points don’t change and steps stay at 0.

If anybody could identify the issue it would be great!

local spawnLocation = workspace:WaitForChild("SpawnLocation")

local function calculateDistanceFromSpawn(character)
	local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
	local playerPosition = humanoidRootPart.Position
	local spawnPosition = spawnLocation.Position
	local distance = (playerPosition - spawnPosition).Magnitude
	return distance
end

local function CalculateDistance(character, points, studs)
	local HRP = character:WaitForChild("HumanoidRootPart")
	local Humanoid = character:WaitForChild("Humanoid")
	local HasDied = false
	Humanoid.Died:Connect(function() HasDied = true end)

	local PreviousPosition = HRP.Position
	repeat
		task.wait(0.1)
		studs.Value = calculateDistanceFromSpawn(character)
		local distanceTravelled = (PreviousPosition - HRP.Position).magnitude
		if distanceTravelled > 1 then
			points.Value += distanceTravelled 
			PreviousPosition = HRP.Position
		end
	until HasDied
end

local DataStoreService = game:GetService("DataStoreService")
local playerDataStore = DataStoreService:GetDataStore("PlayerPoints")
game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player

	local points = Instance.new("NumberValue")
	points.Name = "Points"
	points.Value = 0
	points.Parent = stats
	
	local studs = Instance.new("NumberValue")
	studs.Name = "Studs"
	studs.Value = 0
	studs.Parent = stats

	local function savePoints()
		local success, error = pcall(function()
			playerDataStore:SetAsync(player.UserId .. "_Points", points.Value)
		end)
		if not success then
			warn("Failed to save points for player " .. player.Name .. ": " .. error)
		end
	end

	player.CharacterRemoving:Connect(function(character)
		savePoints()
	end)

	-- Load points if they exist
	local storedPoints = playerDataStore:GetAsync(player.UserId .. "_Points")
	if storedPoints then
		points.Value = storedPoints
	end

	print(player.Name .. " has connected")
	player.CharacterAdded:Connect(function(character)
		CalculateDistance(character, points, studs)
	end)
end)

If you want to test out the (unfinished) game, it’s here: Infinite Corridor - Roblox
Try joining multiple times to see the randomness of the script working/breaking

I don’t know where to start, I changed your script in a way that should make it work. You’re being way to unspecific about your problem and I can’t take the time to explain everything I changed and why I did so in text, if you’d like to get more help and to get in contact with me, either dm me here or add me on dc (Crafter1338)

Here is the (as I interpreted) working version:

local DataStoreService = game:GetService("DataStoreService")
local playerDataStore  = DataStoreService:GetDataStore("PlayerPoints")

local spawnLocation = workspace:WaitForChild("SpawnLocation")

local function distFromSpawn(player)
	if not player.Character then return nil end
	if not player.Character.HumanoidRootPart then return nil end
	
	local character = player.Character

	local playerP = Vector2.new(character.HumanoidRootPart.Position.X, character.HumanoidRootPart.Position.Z)
	local spawnP  = Vector2.new(spawnLocation.Position.X, spawnLocation.Position.Z)

	return (playerP - spawnP).Magnitude
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats 	= Instance.new("Folder")
	leaderstats.Name 	= "leaderstats"
	leaderstats.Parent 	= player

	local points 	= Instance.new("NumberValue")
	points.Name 	="Points"
	points.Value 	= 0
	points.Parent	= leaderstats

	local studs 	= Instance.new("NumberValue")
	studs.Name 		= "Studs"
	studs.Value 	= 0
	studs.Parent	= leaderstats
	
	local newData 	= Instance.new("NumberValue")
	newData.Name 	= "Total"
	newData.Value 	= 0
	newData.Parent	= leaderstats
	
	local success, data = pcall(function()
		return playerDataStore:GetAsync(player.UserId)
	end)
	
	local savedDist = if success then data["distance"] else 0
	local furthestDistance = 0
	
	newData.Value   = savedDist
	
	task.spawn(function()
		while task.wait() do
			local distance = distFromSpawn(player); if distance == nil then continue end
			
			if distance > furthestDistance then 
				furthestDistance = distance
			end
			
			studs.Value   = math.floor(distance)
			newData.Value = math.floor(savedDist + distance)
			points.Value  = math.floor(furthestDistance) + math.floor(savedDist)
		end
	end)
	
	player.CharacterRemoving:Connect(function(character)
		savedDist       += furthestDistance
		newData.Value    = savedDist
		furthestDistance = 0
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, error = pcall(function()
		playerDataStore:SetAsync(player.UserId, {distance = player.leaderstats.Total.Value})
	end)
	
	if not success then
		warn("Failed to save distance for player " .. player.Name .. ": " .. error)
	end
end)

You were on the right path and had the right ideas and I think you would have been able to solve it yourself if you just tried looking throught youtube or the documentation but like I said, feel free to get in touch

kind regards

1 Like