How do i fix this bug that appears when using this system, it just comes out randomly

i need someone to help find out why its spewing out this error when going in reverse image

this code is very messy so i can’t read it, the train error specifically when it stops after going in reverse, it also does not correctly line up with the waypoints set on the track and is prone to breaking randomly, here is he code in question, and it also lags the game a little from inefficient coding

local body = script.Parent.Engine.Body
local main = body.Main
local engine = main.Engine
local wps = script.Parent.Waypoints
local ts = game:GetService("TweenService")

local acceleration = .09
local deceleration = .2
local speed = 0
local accelerating,decelerating,stopping = false,false,false
local door = "closed"
local cwp
local originalspeed = 40
local Main_Dir = 0
local cwpn = 1
local playerwelds = {}
local traveling = false
local cp = 0
local Stopped = false

local glider = Instance.new("Part", script.Parent)
glider.Position = Vector3.new(main.Position.X, wps["1"].Position.Y, main.Position.Z)
glider.Anchored = true
glider.CanCollide = false
glider.Size = Vector3.new(1, 1, 1)
glider.Name = "Train_Glider"
main.Roll:Play()

function Weld(Model)
	for i,v in pairs(Model:GetDescendants()) do
		if v:IsA("BasePart") and v ~= main then
			local wd = Instance.new("Weld", v)
			wd.Name = v.Name.."_Weld"
			wd.Part0 = v
			wd.Part1 = main
			wd.C0 = CFrame.new()
			wd.C1 = main.CFrame:toObjectSpace(v.CFrame)
			v.Anchored = false
		elseif v == main then
			local wd = Instance.new("WeldConstraint", v)
			wd.Name = v.Name.."_Weld"
			wd.Part0 = v
			wd.Part1 = glider
			v.Anchored = false
		end
	end
end

function Accelerate(maxspeed)
	coroutine.resume(coroutine.create(function()
		if maxspeed > speed then
			accelerating = false
			wait(.05)
			accelerating = true
			repeat
				if stopping or decelerating then return end
				game:GetService("RunService").Heartbeat:Wait()
				speed = speed + acceleration
			until speed >= maxspeed
			accelerating = false
		elseif maxspeed < speed then
			decelerating = true
			repeat
				if stopping or accelerating then return end
				game:GetService("RunService").Heartbeat:Wait()
				speed = speed - deceleration
			until speed <= maxspeed
			decelerating = false
		end
	end))
end

function Run_Door(Model)
	coroutine.resume(coroutine.create(function()
		for i,v in pairs(Model:GetChildren()) do
			if v:IsA("Model") then
				spawn(function()
					for i,v in pairs(body:GetDescendants()) do
						if v:IsA("BasePart") then
							v.Anchored = true
						end
					end
					door = "opening"
					local cl = v.PrimaryPart.CFrame
					main.DoorOpen:Play()
					main.Opening:Play()
					for c=0,1,.004 do
						game:GetService("RunService").Heartbeat:Wait()
						if Model:FindFirstChild("Open"..v.Name) then
							local pr = v.PrimaryPart
							local cf = pr.CFrame:Lerp(Model["Open"..v.Name].CFrame, (c*(c))*0.2)
							v:SetPrimaryPartCFrame(cf)
						end
					end
					door = "open"
					wait(20)
					main.ClosingAnnouncement:Play()
					wait(main.ClosingAnnouncement.TimeLength)
					main.DoorClose:Play()
					wait(3)
					for c=0,1,.0035 do
						game:GetService("RunService").Heartbeat:Wait()
						local pr = v.PrimaryPart
						local cf = pr.CFrame:Lerp(cl, (c*(c))*0.1)
						v:SetPrimaryPartCFrame(cf)
					end
					door = "closed"
					for i,v in pairs(body:GetDescendants()) do
						if v:IsA("BasePart") then
							v.Anchored = false
						end
					end
				end)
			end
		end
	end))
end

function DoorRun()
	Run_Door(body.Doors)
	Run_Door(script.Parent.Parent.StationDoors[script.Parent.NextStop.Value].Doors)
	repeat wait() until door == "closed"
end

function Stop()
	main.Brake:Play()
	stopping = true
	decelerating = true
	local spd = speed
	local dist = (glider.Position-cwp.Position).Magnitude
	originalspeed = speed
	while (glider.Position-cwp.Position).Magnitude >= .8 do
		game:GetService("RunService").Heartbeat:Wait()
		speed = ((spd/dist)*(glider.Position-cwp.Position)).Magnitude
		if not stopping then return end
	end
	speed = 0
	Remove_Player_Welds()
	if not wps:FindFirstChild(cwpn-1) then
		script.Parent.Direction.Value = 1
	elseif not wps:FindFirstChild(#wps:GetChildren()+1) then
		script.Parent.Direction.Value = -1
	end
	wait(1)
	decelerating = false
	stopping = false
	Stopped = true
	coroutine.resume(coroutine.create(function()
		DoorRun()
		Player_Weld()
		if not wps:FindFirstChild(cwpn-1) then
			script.Parent.Direction.Value = 1
		elseif not wps:FindFirstChild(cwpn+1) then
			script.Parent.Direction.Value = -1
		end
		main.Depart:Play()
		wait(2.5)
		if not traveling then
			if cwp:FindFirstChild("DepartSpeed") then
				Accelerate(cwp.DepartSpeed.Value)
			else
				Accelerate(originalspeed)
			end
			if not wps:FindFirstChild(tostring(cwpn-1)) then
				Travel(1)
			elseif not wps:FindFirstChild(tostring(cwpn+1)) then
				Travel(-1)
			end
		end
	end))
end

function Player_Weld()
	local Region = Region3.new(
		Vector3.new(
			main.Position.X - main.Size.X/2,
			main.Position.Y - main.Size.Y/2,
			main.Position.Z - main.Size.Z/2		
		),
		Vector3.new(
			main.Position.X + main.Size.X/2,
			main.Position.Y + 8,
			main.Position.Z + main.Size.Z/2				
		)
	)
	
	for _,Part in pairs(game.Workspace:FindPartsInRegion3(Region,nil,math.huge)) do
		if Part ~= nil and Part.ClassName == "Part" and Part.Name == "HumanoidRootPart" then
			if Part.Parent:FindFirstChild("Humanoid") then
				if not Part.Parent.Humanoid.Sit then
					local wd = Instance.new("WeldConstraint", Part.Parent.HumanoidRootPart)
					wd.Part0 = Part.Parent.HumanoidRootPart
					wd.Part1 = main
					wd.Name = "CE_Train_Weld"
					Part.Parent.Humanoid.JumpPower = 0
					Part.Parent.Humanoid.PlatformStand = true
					playerwelds[#playerwelds+1] = wd
				end
			end
		end
	end
end

function Remove_Player_Welds()
	for i,v in pairs(playerwelds) do
		pcall(function()
			v.Part0.Parent.Humanoid.JumpPower = 50
			v.Part0.Parent.Humanoid.PlatformStand = false
			playerwelds[#playerwelds+1] = nil
			v:Destroy()
		end)
	end
end

function Travel(Dir)
	Player_Weld()
	warn(Dir)
	if Dir == 1 then
		traveling = true
		wait(1)
		Main_Dir = 0
		local w = 0
		for w2=1,#wps:GetChildren() do
			w = w + 1
			local v = wps[tostring(w)]
			cwp = v
			cwpn = w
			if not v:FindFirstChild("StationName") then Stopped = false end
			if v:FindFirstChild("StationName") and not Stopped then repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 18+(speed*.5) else repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 21 end
			if v:FindFirstChild("StationName") and not Stopped then script.Parent.NextStop.Value = v.StationName.Value repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 50+(speed*12) Stop() traveling = false end
			if v:FindFirstChild("SetSpeed") then if v.SetSpeed.TargetDirection.Value == 1 and script.Parent.Direction.Value == 1 then Accelerate(v.SetSpeed.Value) end end
		end
		traveling = false
	elseif Dir == -1 then
		traveling = true
		wait(1)
		Main_Dir = -1
		local w = #wps:GetChildren()-1
		for w2=1,#wps:GetChildren() do
			w = w - 1
			local v = wps[w]
			cwp = v
			cwpn = w
			if not v:FindFirstChild("StationName") then Stopped = false end
			if v:FindFirstChild("StationName") and not Stopped then repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 18+(speed*.5) else repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 21 end
			if v:FindFirstChild("StationName") and not Stopped then script.Parent.NextStop.Value = v.StationName.Value repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 50+(speed*12) Stop() traveling = false end
			if v:FindFirstChild("SetSpeed") then if v.SetSpeed.TargetDirection.Value == -1 and script.Parent.Direction.Value == -1 then Accelerate(v.SetSpeed.Value) end end
		end
		cwpn = 1
		traveling = false
	end
end
main.Engine:Play()
game:GetService("RunService").Heartbeat:Connect(function()
	if cwp then glider.CFrame = glider.CFrame:Lerp(CFrame.new(glider.CFrame.p, cwp.CFrame.p)*CFrame.Angles(0, math.rad(180)*Main_Dir, 0), .05*(speed*.03)) end
	glider.CFrame = glider.CFrame * CFrame.new(0, 0, -math.rad(speed)*script.Parent.Direction.Value)
	body.MainBody.Floor.Velocity = glider.CFrame.LookVector*speed*script.Parent.Direction.Value
	main.Engine.Pitch = speed*.02
	main.Engine.Volume = speed*.07
	main.Roll.Volume = speed*.02
	if main.Engine.Volume >= 1 then main.Engine.Volume = 1 end
	if main.Engine.Pitch >= 1.07 then main.Engine.Pitch = 1.07 end
	if main.Roll.Volume >= 1.3 then main.Roll.Volume = 1.3 end
end)
Weld(body)
wait(1)
Accelerate(originalspeed)
Travel(1)

any and all help is appreciated, and if it ends up being unfix-able please show me some alternatives
thanks, i only have 175 robux so i cant pay well.

[oh_no.rbxm (184.0 KB)

Uhh… you only show where it shows the stack begin and end. Can you show the actual error? It should be red and bold. Also, did you make this yourself?

Like you said the code is very messy and you can’t read it. Neither can I. I can’t help without being able to read it. Also, there’s alot of code to read!

If the code is messy and inefficient, make it yourself or hire someone to do it for you.

opps, sorry i will inclue the stack begin
no i did not make this, someone gave it to me as they did not need it anymore
i can code a train system like this but not as advanced, but ill try to format it into a understandable angle since the code itself is very hard to watch

here is the error image i tried making a 0 waypoint but it makes the train die

Then “0” isn’t a valid member of Waypoints.

If you will, try using FindFirstChild so you dont get game breaking errors like that.

interesting, i added a 0 waypoint and it makes the train goes reverse, i think ill just make my own train system but thanks for the help