Problem with for loop and distance

So basically I am using string value attributes to be as factions. I’m making it so that if 2 npcs have at least one matching attribute then they would not attack each other, like for example NPC 1 has factions Human and Demon and NPC 2 has factions Human and Alien then they would be allies because of the matching attribute: Human. The problem is that the for loop isn’t going to the next instance to check them. For example, an npc and its ally are 5 studs apart so if the enemy is 10 studs away from the both of them, the script will be stuck on the ally npc and not check that there is an enemy nearby because the ally npc is the nearest to the npc. I don’t understand why the loop won’t just go forward once it realizes that the ally is an ally.

function findTarget(pos)
	local target = nil
	local range = 10000 - detect range
	for i, v in ipairs(workspace:GetChildren()) do -- isn't going to the next 'v'
		local model = v:IsA("Model") and v ~= npc
		if model then
			local nhum = v:FindFirstChild("Humanoid")
			local nhrp = v:FindFirstChild("HumanoidRootPart")
			local nfac = v:FindFirstChild("Faction")
			local natt = nfac:GetAttributes()
			if nhum and nhum.Health > 0 and nhrp and nfac then
				if(nhrp.Position - pos).Magnitude < range then -- if distance < detect range
					print(nhrp.Parent)
					for i, v in pairs(faction) do
						for l, j in pairs(natt) do
							if i == l then
								target = nil -- if both attributes match, no target(at least 1 matched).
							else
								target = nhrp
								range = (nhrp.Position - pos).Magnitude
							end
						end
					end
				end
			end
		end
	end
	return target
end

while true do
	wait()
	local target = findTarget(hrp.Position)
	if target then
		path.Visualize = true
		path:SetHipHeight(1)
		path:Run(target.Position)
	end
end


The NPCs are only going after the red guy if it’s closer to them than their own allies which is confusing.

Red = Enemy
Skin Color = NPCs

I don’t know how to approach an NPC having multiple factions so I’m using attributes but it may be inefficient.

From my understanding that if statement ends when i == 1 but there is nothing else pass that.Did the loop finish? Also what variable is detect range when defining range?Also when you day the loop does not go forward do you mean it doesn’t stop?

Hard to explain so I added another part of the script and a video demonstration. The loop doesn’t stop, well it does but doesn’t at the same time.

Now I think that checking the instance for the enemy might not be the most efficient way of checking for enemy. You could maybe check for a specific value. This start to get a bit out of my knowledge range.But I will try to see what is wrong.Also have you tried using corountines

Yes, I’ve tried using coroutines but for different uses. I don’t see where I would use coroutine for this though.

Hmm, perhaps you could make an ignore list for the nearest allies. You’d skip every ally until you find an enemy.