Auto Bot not Working

Hello! I am making a border game and we are making a bot that asks you questions and if you respond correctly, you can pass and not die. But we have a problem where it stays open whenever you’re in. Here is the script. I hope you can help!

local gate = script.Parent

local door1 = workspace.Map.Border.Wall.Gate.DoorSystem.Door1
local door2 = workspace.Map.Border.Wall.Gate.DoorSystem.Door2
local roomSpace = workspace.GuardBotPart
local gatekeeper = gate:WaitForChild("Gatekeeper")
local chatService = game:GetService("Chat")
local players = game:GetService("Players")
local RunService = game:GetService("RunService")

local killZone = workspace.KillZone
local npcTemplate = script.Parent.Parent:WaitForChild("GuardMassacre")
local npc = workspace:FindFirstChild("GuardMassacre") or npcTemplate:Clone()
npc.Parent = workspace

local playersInRoom = {}
local dialogueStates = {}
local activeTargets = {}
local chasing = false

-- Kill a player
local function killPlayer(player)
	local character = player.Character
	if character and character:FindFirstChild("Humanoid") then
		character.Humanoid.Health = 0
	end
end

-- Players in kill zone
local function getTouchingPlayers()
	local touchingPlayers = {}
	for _, player in ipairs(players:GetPlayers()) do
		local char = player.Character
		if char and char:FindFirstChild("HumanoidRootPart") and killZone:IsA("BasePart") then
			if (killZone.Position - char.HumanoidRootPart.Position).Magnitude < (killZone.Size.Magnitude / 2) then
				table.insert(touchingPlayers, player)
			end
		end
	end
	return touchingPlayers
end

-- Chase targets
local function chaseAllTargets()
	if chasing then return end
	chasing = true

	for player, _ in pairs(activeTargets) do
		coroutine.wrap(function()
			local humanoid = npc:FindFirstChild("Humanoid")
			local rootPart = npc:FindFirstChild("HumanoidRootPart")
			if not humanoid or not rootPart then return end

			local character = player.Character
			if not character or not character:FindFirstChild("HumanoidRootPart") then return end

			while activeTargets[player] and character:FindFirstChild("HumanoidRootPart") do
				local targetPos = character.HumanoidRootPart.Position
				local npcPos = rootPart.Position
				local direction = (targetPos - npcPos).Unit
				local moveToPosition = npcPos + direction * 10

				humanoid:MoveTo(moveToPosition)

				if (targetPos - npcPos).Magnitude < 5 then
					killPlayer(player)
					activeTargets[player] = nil

					task.wait(6)
					local newClone = npcTemplate:Clone()
					newClone.Parent = workspace
					newClone.PrimaryPart.CFrame = CFrame.new(-16.5, 13.501, -78)
					npc:Destroy()
					npc = newClone
					break
				end
				task.wait(0.2)
			end
		end)()
	end

	task.delay(10, function()
		chasing = false
	end)
end

-- Gatekeeper dialogue
local function gatekeeperSay(text)
	local head = gatekeeper:FindFirstChild("Head")
	if head then
		chatService:Chat(head, text, Enum.ChatColor.White)
	end
end

-- Door functions
local function openDoor1()
	if next(playersInRoom) == nil then
		door1.CanCollide = false
		door1.Transparency = 0.5
		print("Door1 opened")
	end
end

local function closeDoor1()
	door1.CanCollide = true
	door1.Transparency = 0
	print("Door1 closed")
end

local function openDoor2()
	door2.CanCollide = false
	door2.Transparency = 0.5
	print("Door2 opened")
end

local function closeDoor2()
	task.wait(2)
	door2.CanCollide = true
	door2.Transparency = 0
	print("Door2 closed")
end

-- Dialogue handling
local function beginDialogue(player)
	if dialogueStates[player] then return end

	dialogueStates[player] = {
		step = 1,
		name = nil,
		reason = nil,
		toolCheckStarted = false,
	}

	gatekeeperSay("What is your name?")
end

local function startToolCheckLoop(player)
	local state = dialogueStates[player]
	if not state or state.toolCheckStarted then return end
	state.toolCheckStarted = true

	coroutine.wrap(function()
		while playersInRoom[player] do
			local character = player.Character
			local tool = character and character:FindFirstChildOfClass("Tool")

			if tool then
				if tool.Name == "Passport" then
					gatekeeperSay("Thank you, " .. (state.name or "guest") .. ". You may proceed.")
					openDoor2()
					break
				elseif tool.Name == "Fake Passport" then
					local chance = math.random(1, 4)

					if chance == 1 then
						gatekeeperSay("I said, no fake passports!")
						local touching = getTouchingPlayers()
						for _, plr in ipairs(touching) do
							activeTargets[plr] = true
						end
						chatService:Chat(npc.Head, "YOU'RE UNDER ARREST!", Enum.ChatColor.White)
						chaseAllTargets()
					else
						gatekeeperSay("Thank you, " .. (state.name or "guest") .. ". You may proceed.")
						openDoor2()
					end
					break
				end
			end
			task.wait(1)
		end
	end)()
end

-- Handle player chats for dialogue
players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		local state = dialogueStates[player]
		if not state then return end

		if state.step == 1 then
			state.name = message
			state.step = 2
			gatekeeperSay("Why are you here?")
		elseif state.step == 2 then
			state.reason = message
			state.step = 3
			gatekeeperSay("Please hold up your Passport. No Fakes!")
			startToolCheckLoop(player)
		end
	end)
end)

-- Player enters room
roomSpace.Touched:Connect(function(hit)
	local character = hit:FindFirstAncestorOfClass("Model")
	local player = players:GetPlayerFromCharacter(character)

	if player and not playersInRoom[player] then
		print("Player touched RoomSpace:", player.Name)
		playersInRoom[player] = true

		local count = 0
		for _ in pairs(playersInRoom) do count += 1 end

		if count >= 2 then
			local touching = getTouchingPlayers()
			for _, plr in ipairs(touching) do
				activeTargets[plr] = true
			end
			chatService:Chat(npc.Head, "YOU'RE UNDER ARREST!", Enum.ChatColor.White)
			chaseAllTargets()
			playersInRoom = {}
			return
		end

		task.delay(2, function()
			closeDoor2()
		end)
		task.wait(1)
		beginDialogue(player)
	end
end)

-- Player leaves room
roomSpace.TouchEnded:Connect(function(hit)
	local character = hit:FindFirstAncestorOfClass("Model")
	local player = players:GetPlayerFromCharacter(character)
	workspace.NextPersonEnterTxt.Sound:Play()
	chatService:Chat(workspace.NextPersonEnterTxt, "NEXT PERSON ENTER", Enum.ChatColor.White)

	if player then
		print("Player left RoomSpace:", player.Name)
		playersInRoom[player] = nil
		dialogueStates[player] = nil
		openDoor1()
		close
	end
end)

-- Initialize on start
openDoor1()

1 Like