Unknown error in script

Hello so the script below is part of a trail system I have in my game and it attaches the trail to the player each time they respawn. The only problem is when the player first loads in and clicks the equip button the trail does not attach to the player until they die. After that the script great. Any ideas what the problem might be or how I can fix this?

local dss = game:GetService(“DataStoreService”)
local ds = dss:GetDataStore(“DATA”)
local trails = game.ReplicatedStorage:WaitForChild(“Trails”)

function saveData(plrLeaving)
local ownedTrails = {}
for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
table.insert(ownedTrails, trail.Name)
end
local success, err = pcall(function()
ds:SetAsync(“trails-” … plrLeaving.UserId, ownedTrails)
ds:SetAsync(“Coins-” … plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
end)
end

game.Players.PlayerAdded:Connect(function(plr)
local trailsOwned = {}
pcall(function()
trailsOwned = ds:GetAsync(“trails-” … plr.UserId) or {}
end)
local ownedFolder = Instance.new(“Folder”, plr)
ownedFolder.Name = “OwnedTrails”
for i, owned in pairs(trailsOwned) do
if trails:FindFirstChild(owned) then
trails[owned]:Clone().Parent = ownedFolder
end
end
plr.CharacterAdded:Connect(function(char)
local hrp = char:WaitForChild(“HumanoidRootPart”)
local atchTop = Instance.new(“Attachment”, hrp)
atchTop.Name = “TrailTop”
atchTop.Position = Vector3.new(0, 0.766, 0)
local atchBtm = Instance.new(“Attachment”, hrp)
atchBtm.Name = “TrailBottom”
atchBtm.Position = Vector3.new(0, -0.766, 0)
if plr:FindFirstChild(“LastTrail”) then
local newTrail = plr:FindFirstChild(“LastTrail”).Value:Clone()
newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
newTrail.Parent = char.HumanoidRootPart
end
end)
end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
for i, plrLeaving in pairs(game.Players:GetPlayers()) do
saveData(plrLeaving)
end
end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
local price = trail.Price.Value
local coins = plr.leaderstats.Coins
if price <= coins.Value then
coins.Value -= price
trail:Clone().Parent = plr.OwnedTrails
end
elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
if plr:FindFirstChild(“LastTrail”) then
plr:FindFirstChild(“LastTrail”).Value = trail
else
local obj = Instance.new(“ObjectValue”)
obj.Parent = plr
obj.Name = “LastTrail”
obj.Value = trail
end
local char = plr.Character
if not char or not char:FindFirstChild(“HumanoidRootPart”) then return end
for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
if child:IsA(“Trail”) then child:Destroy() end
end
local newTrail = trail:Clone()
newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
newTrail.Parent = char.HumanoidRootPart
end
end)

Please consider using codeblocks
```
– code here
```

The script is running after the player character loads for the first time, causing it to make an exclusion for their first spawn. What you should do instead is make CharacterAdded a function then check if their character is already loaded.

function CharacterAdded(char)
--your CharacterAdded code
end
CharacterAdded(player.Character or player.CharacterAdded:Wait()) 
player.CharacterAdded:Connect(CharacterAdded)

Edit: Also consider using codeblocks when making topics, it helps people understand your code without having to open Roblox studio.

1 Like

Ok thanks will do. I didn’t know what they were so I just deleted them my bad.

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local trails = game.ReplicatedStorage:WaitForChild("Trails")

function saveData(plrLeaving)
	local ownedTrails = {}
	for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
		table.insert(ownedTrails, trail.Name)
	end
	local success, err = pcall(function()
		ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
		ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local trailsOwned = {}
	pcall(function()
		trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}
	end)
	local ownedFolder = Instance.new("Folder", plr)
	ownedFolder.Name = "OwnedTrails"
	for i, owned in pairs(trailsOwned) do
		if trails:FindFirstChild(owned) then
			trails[owned]:Clone().Parent = ownedFolder
		end
	end
	plr.CharacterAdded:Connect(function(char)
		local hrp = char:WaitForChild("HumanoidRootPart")
		local atchTop = Instance.new("Attachment", hrp)
		atchTop.Name = "TrailTop"
		atchTop.Position = Vector3.new(0, 0.766, 0)
		local atchBtm = Instance.new("Attachment", hrp)
		atchBtm.Name = "TrailBottom"
		atchBtm.Position = Vector3.new(0, -0.766, 0)
		if plr:FindFirstChild("LastTrail") then
			local newTrail = plr:FindFirstChild("LastTrail").Value:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	end)
end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	for i, plrLeaving in pairs(game.Players:GetPlayers()) do
		saveData(plrLeaving)
	end
end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr.OwnedTrails
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		if plr:FindFirstChild("LastTrail") then
			plr:FindFirstChild("LastTrail").Value = trail
		else
			local obj = Instance.new("ObjectValue")
			obj.Parent = plr
			obj.Name = "LastTrail"
			obj.Value = trail
		end
		local char = plr.Character
		if not char or not char:FindFirstChild("HumanoidRootPart") then return end
		for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
		newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
		newTrail.Parent = char.HumanoidRootPart
	end
end)

For those complaining about format.

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local trails = game.ReplicatedStorage:WaitForChild("Trails")

function saveData(plrLeaving)
	local ownedTrails = {}
	for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
		table.insert(ownedTrails, trail.Name)
	end
	local success, err = pcall(function()
		ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
		ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local trailsOwned = {}
	pcall(function()
		trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}
	end)
	local ownedFolder = Instance.new("Folder", plr)
	ownedFolder.Name = "OwnedTrails"
	for i, owned in pairs(trailsOwned) do
		if trails:FindFirstChild(owned) then
			trails[owned]:Clone().Parent = ownedFolder
		end
	end
	plr.CharacterAdded:Connect(function(char)
		local hrp = char:WaitForChild("HumanoidRootPart")
		local atchTop = Instance.new("Attachment", hrp)
		atchTop.Name = "TrailTop"
		atchTop.Position = Vector3.new(0, 0.766, 0)
		local atchBtm = Instance.new("Attachment", hrp)
		atchBtm.Name = "TrailBottom"
		atchBtm.Position = Vector3.new(0, -0.766, 0)
		if plr:FindFirstChild("LastTrail") then
			local newTrail = plr:FindFirstChild("LastTrail").Value:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	end)
end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	for i, plrLeaving in pairs(game.Players:GetPlayers()) do
		saveData(plrLeaving)
	end
end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr.OwnedTrails
			local char = plr.Character
			if not char or not char:FindFirstChild("HumanoidRootPart") then return end
			for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
				if child:IsA("Trail") then child:Destroy() end
			end
			local newTrail = trail:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		if plr:FindFirstChild("LastTrail") then
			plr:FindFirstChild("LastTrail").Value = trail
		else
			local obj = Instance.new("ObjectValue")
			obj.Parent = plr
			obj.Name = "LastTrail"
			obj.Value = trail
		end
		local char = plr.Character
		if not char or not char:FindFirstChild("HumanoidRootPart") then return end
		for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
		newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
		newTrail.Parent = char.HumanoidRootPart
	end
end)

You just needed to duplicate the block of code which adds the trail if they have already purchased the trail and attempted to equip it into the area which handles first-time purchases.

I got a error is says TrailTop is not a valid member of Part “Workspace.Iimitedquantity.HumanoidRootPart”.

plr.CharacterAdded:Connect(function(char)
	local hrp = char:WaitForChild("HumanoidRootPart")
	local atchTop = Instance.new("Attachment", hrp)
	atchTop.Name = "TrailTop"
	atchTop.Position = Vector3.new(0, 0.766, 0)
	local atchBtm = Instance.new("Attachment", hrp)
	atchBtm.Name = "TrailBottom"
	atchBtm.Position = Vector3.new(0, -0.766, 0)

Isn’t every character given “TrailTop” though?

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local trails = game.ReplicatedStorage:WaitForChild("Trails")

function saveData(plrLeaving)
	local ownedTrails = {}
	for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
		table.insert(ownedTrails, trail.Name)
	end
	local success, err = pcall(function()
		ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
		ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local trailsOwned = {}
	pcall(function()
		trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}
	end)
	local ownedFolder = Instance.new("Folder")
	ownerFolder.Parent = plr
	ownedFolder.Name = "OwnedTrails"
	for i, owned in pairs(trailsOwned) do
		if trails:FindFirstChild(owned) then
			trails[owned]:Clone().Parent = ownedFolder
		end
	end
	plr.CharacterAdded:Connect(function(char)
		local hrp = char:WaitForChild("HumanoidRootPart")
		local atchTop = Instance.new("Attachment")
		atchTop.Parent = hrp
		atchTop.Name = "TrailTop"
		atchTop.Position = Vector3.new(0, 0.766, 0)
		local atchBtm = Instance.new("Attachment")
		atchBtm.Parent = hrp
		atchBtm.Name = "TrailBottom"
		atchBtm.Position = Vector3.new(0, -0.766, 0)
		if plr:FindFirstChild("LastTrail") then
			local newTrail = plr:FindFirstChild("LastTrail").Value:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	end)
end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	for i, plrLeaving in pairs(game.Players:GetPlayers()) do
		saveData(plrLeaving)
	end
end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr.OwnedTrails
			local char = plr.Character
			if not char or not char:FindFirstChild("HumanoidRootPart") then return end
			for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
				if child:IsA("Trail") then child:Destroy() end
			end
			local newTrail = trail:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		if plr:FindFirstChild("LastTrail") then
			plr:FindFirstChild("LastTrail").Value = trail
		else
			local obj = Instance.new("ObjectValue")
			obj.Parent = plr
			obj.Name = "LastTrail"
			obj.Value = trail
		end
		local char = plr.Character
		if not char or not char:FindFirstChild("HumanoidRootPart") then return end
		for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
		newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
		newTrail.Parent = char.HumanoidRootPart
	end
end)

Im going to try copying and pasting yours to see I made a error.

Its still saying TrailTop is not a valid member of “Workspace.iimitedquantity.HumanoidRootPart” which makes no sense.

No idea, that means the entire script has broken then since all I did was copied the code from the bit where the trail is applied when you attempt to equip a purchased trail to the bit where it equips when you purchase a trail for the first time.

Check your HRP when playing does it have the attachment instance?

I’m no longer on my pc but when I get back on later I’ll check and tell you.

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr:WaitForChild("OwnedTrails")
			local char = plr.Character
			local hrp = char:WaitForChild("HumanoidRootPart")
			if not char or not hrp then return end
			for i, child in pairs(hrp:GetChildren()) do
				if child:IsA("Trail") then child:Destroy() end
			end
			local newTrail = trail:Clone()
			newTrail.Attachment0 = hrp:WaitForChild("TrailTop")
			newTrail.Attachment1 = hrp:WaitForChild("TrailBottom")
			newTrail.Parent = hrp
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		if plr:FindFirstChild("LastTrail") then
			plr:FindFirstChild("LastTrail").Value = trail
		else
			local obj = Instance.new("ObjectValue")
			obj.Parent = plr
			obj.Name = "LastTrail"
			obj.Value = trail
		end
		local char = plr.Character
		local hrp = char:WaitForChild("HumanoidRootPart")
		if not char or not hrp then return end
		for i, child in pairs(hrp:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = hrp:WaitForChild("TrailTop")
		newTrail.Attachment1 = hrp:WaitForChild("TrailBottom")
		newTrail.Parent = hrp
	end
end)

So it is doing the same thing. When I first spawn and click equip it doesn’t equip until I die. But now the error is 'Infinite yield possible on ‘Workspace.Iimitedquantity.HumanoidRootPart:WaitForChild(“TrailTop”)’. This is so frustrating I have to get this game out soon.

local dss = game:GetService(“DataStoreService”)
local ds = dss:GetDataStore(“DATA”)
local trails = game.ReplicatedStorage:WaitForChild(“Trails”)

function saveData(plrLeaving)
local ownedTrails = {}
for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
table.insert(ownedTrails, trail.Name)
end
local success, err = pcall(function()
ds:SetAsync(“trails-” … plrLeaving.UserId, ownedTrails)
ds:SetAsync(“Coins-” … plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
end)
end

game.Players.PlayerAdded:Connect(function(plr)
local trailsOwned = {}
pcall(function()
trailsOwned = ds:GetAsync(“trails-” … plr.UserId) or {}
end)
local ownedFolder = Instance.new(“Folder”, plr)
ownedFolder.Parent = plr
ownedFolder.Name = “OwnedTrails”
for i, owned in pairs(trailsOwned) do
if trails:FindFirstChild(owned) then
trails[owned]:Clone().Parent = ownedFolder
end
end
plr.CharacterAdded:Connect(function(char)
local hrp = char:WaitForChild(“HumanoidRootPart”)
local atchTop = Instance.new(“Attachment”, hrp)
atchTop.Name = “TrailTop”
atchTop.Position = Vector3.new(0, 0.766, 0)
local atchBtm = Instance.new(“Attachment”, hrp)
atchBtm.Name = “TrailBottom”
atchBtm.Position = Vector3.new(0, -0.766, 0)
if plr:FindFirstChild(“LastTrail”) then
local newTrail = plr:FindFirstChild(“LastTrail”).Value:Clone()
newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
newTrail.Parent = char.HumanoidRootPart
end
end)
end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
for i, plrLeaving in pairs(game.Players:GetPlayers()) do
saveData(plrLeaving)
end
end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
local price = trail.Price.Value
local coins = plr.leaderstats.Coins
if price <= coins.Value then
coins.Value -= price
trail:Clone().Parent = plr:WaitForChild(“OwnedTrails”)
local char = plr.Character
local hrp = char:WaitForChild(“HumanoidRootPart”)
if not char or not hrp then return end
for i, child in pairs(hrp:GetChildren()) do
if child:IsA(“Trail”) then child:Destroy() end
end
local newTrail = trail:Clone()
newTrail.Attachment0 = hrp:WaitForChild(“TrailTop”)
newTrail.Attachment1 = hrp:WaitForChild(“TrailBottom”)
newTrail.Parent = hrp
end
elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
if plr:FindFirstChild(“LastTrail”) then
plr:FindFirstChild(“LastTrail”).Value = trail
else
local obj = Instance.new(“ObjectValue”)
obj.Parent = plr
obj.Name = “LastTrail”
obj.Value = trail
end
local char = plr.Character
local hrp = char:WaitForChild(“HumanoidRootPart”)
if not char or not hrp then return end
for i, child in pairs(hrp:GetChildren()) do
if child:IsA(“Trail”) then child:Destroy() end
end
local newTrail = trail:Clone()
newTrail.Attachment0 = hrp:WaitForChild(“TrailTop”)
newTrail.Attachment1 = hrp:WaitForChild(“TrailBottom”)
newTrail.Parent = hrp
end
end)

This is the code right I don’t think I did anything wrong.