Junction System (ModuleScripts, LocalScripts and Scripts involved)

  1. What do you want to achieve? I want to make a intelligent junction system.

  2. What is the issue? Something switches the first junction, after the junction’s original state has been restored, without any intention of switching it again.

  3. What solutions have you tried so far? I have tried debugging, however that does not really help.

Code:
— Main Junction Script (Script) —


local JunctionsFolder = game.Workspace.JunctionSensors
local JunctionsModule = require(game.ServerScriptService.JunctionModule)

for i, v in ipairs(JunctionsFolder:GetChildren()) do
	if v.Name == 'JunctionRamp' then
		v.Touched:Connect(function(hit)
			if hit.Name == 'Hit' then
				local Driver = game.Players:FindFirstChild(hit.Parent:WaitForChild('Driver').Value)
				JunctionsModule.GivePlayerUI(Driver,v)
			end
		end)
	elseif v.Name == 'SensorAccept' then
		v.Touched:Connect(function(hit)
			if hit.Name == 'Hit' then
				local Driver = game.Players:FindFirstChild(hit.Parent:WaitForChild('Driver').Value)
				JunctionsModule.SetJunction(Driver,v)
			end
		end)
	elseif v.Name == 'SensorOff' then
		v.Touched:Connect(function(hit)
			if hit.Name == 'Hit' then
				local Driver = game.Players:FindFirstChild(hit.Parent:WaitForChild('Driver').Value)
				JunctionsModule.ResetJunction(Driver,v)
			end
		end)
	end
end

— Main module script —

-- // Services \\ --
local ServerScriptStorage = game.ServerScriptService
local ReplicatedStorage = game.ReplicatedStorage

-- // Required Material \\ --
local JunctionModule = {}
local UI_Test = script.Frame
local RemoteEventFolder = ReplicatedStorage.RemoteEvents
local JunctionFolder = workspace.Junctions

JunctionModule.GivePlayerUI = function(player,sensor)
	if not sensor:IsA('Part') then
		return 'Sensor Object is not a value'
	end
	if sensor.Name == 'JunctionRamp' then
		local DriveUI = Instance.new("ScreenGui")
		DriveUI.Name = 'JunctionUI'
		DriveUI.Parent = player:WaitForChild('PlayerGui')
		UI_Test:Clone().Parent = DriveUI
	end
end

JunctionModule.SetJunction = function(player,sensor)
	if not sensor:IsA('Part') then
		return 'Sensor Object is not a value'
	end
	
	if sensor.Name == 'SensorAccept' then
		local Settings = sensor:WaitForChild('Settings')
		if not Settings.Parent == sensor then
			return 'No settings exist.'
		end 
		local Direction = ''
		local LeftBranch = Settings.Left.Value
		local RightBranch = Settings.Right.Value
		print('LeftBranchName: '..LeftBranch.Name)
		print('RightBranchName: '..RightBranch.Name)
		
		RemoteEventFolder.JunctionChecker:FireClient(player,'Junction Check')
		print('Event Sent')
		RemoteEventFolder.JunctionChecker.OnServerEvent:Connect(function(player,args)
			
			print('Returned Value: '..args)
			
			if args == 'Left' then
				LeftBranch.Transparency = 0
				LeftBranch.CanCollide = true
				RightBranch.CanCollide = false
				RightBranch.Transparency = 0.5
				local DriveUI = player:WaitForChild('PlayerGui'):WaitForChild('JunctionUI')
				DriveUI:Destroy()
				Direction = 'Left'
			elseif args == 'Right' then
				LeftBranch.Transparency = 0.5
				LeftBranch.CanCollide = false
				RightBranch.CanCollide = true
				RightBranch.Transparency = 0
				local DriveUI = player:WaitForChild('PlayerGui'):WaitForChild('JunctionUI')
				DriveUI:Destroy()
				Direction = 'Left'
			else
				return 'Junction not set due to no selection.'
			end
		end)
		
	end
end

JunctionModule.ResetJunction = function(player,sensor)
	if sensor.Name == 'SensorOff' then
		local Settings = sensor:WaitForChild('Settings')
		if not Settings.Parent == sensor then
			return 'No settings exist.'
		end 

		local LeftBranch = Settings.Left.Value
		local RightBranch = Settings.Right.Value
				LeftBranch.Transparency = 0
				LeftBranch.CanCollide = true
				RightBranch.CanCollide = true
				RightBranch.Transparency = 0
	end
end


return JunctionModule

— Local Script Responsible For Junction Deciding —

 -- // Variables \\ --
local ReplicatedStorage = game.ReplicatedStorage
local EventFolder = ReplicatedStorage.RemoteEvents
local Event = EventFolder.JunctionChecker
local Selection = script.Parent.Selection
local HTTPLogger = EventFolder.HTTPLogger

Event.OnClientEvent:Connect(function(args)
	local SelectionValue = Selection.Value
	print('Event Recieved')
	print('Argument: '..args)
	if args == 'Junction Check' then
		warn('SelectionValue: '.. SelectionValue)
		Event:FireServer(SelectionValue)
	else
		Event:FireServer('No')
		HTTPLogger:FireServer('JunctionModule')
	end
end)

This is the first step. The train (on the right) firstly goes over a red block, which promts the driver to select the direction. Then the driver reaches the yellow block, where the junction (red circled) has to be set correctly. The junction prompt gets destroyed at this block.

This step works fine…

In this case, the driver decides to go to the right (following the red arrow). At the red colored block, the driver gets another prompt to select the next junction setting. When passing the red circled blue colored block, the first junction resets.

Until now, everything is fine.

The problem is, that once I have passed the circled yellow sensor, the first (not fully circled) junction sets the same aspect as selected for the second junction.

When the response comes back from the second junction, it prints out the response twice. (Red line is the difference between the first junction (above the first line) and the second junction (below the red line))

image