Why is my for loop stopping?

  1. What do you want to achieve? Keep it simple and clear!
    I am trying to loop through some waypoints to see which one is available and then the npc goes to it.

  2. What is the issue? Include screenshots / videos if possible!
    The loop stops after the if statement returns false.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried looking through the docs and through a couple of youtube videos.

My Code

local NPC = script.Parent.Humanoid
local WayPoints = game.Workspace.Position:GetChildren()
local Action = game.Workspace.Position.Action
local OwnsPoint = false

local function March()
	for i, Point in pairs(WayPoints) do
		if Point.Name == "Legionary" and not Point:FindFirstChild("Owner") and not OwnsPoint and Action ~= "Charge" then
			local OwnsPoint = Instance.new("StringValue")
			OwnsPoint.Name = "Owner"
			OwnsPoint.Parent = Point
			OwnsPoint.Value = script.Parent.Name
			
			NPC:MoveTo(Point.Position)
		elseif Action == "Charge" then
			print("Charge")
		end
	end
end

while wait() do
	March()
end

Note;
This script is a server script inside of the npc.

1 Like

Have you tried printing the WayPoints list? Would it be possible to see it?

Also, I might be wrong on this, but lists in Lua are not consistently ordered, meaning you may get the waypoints in different orders.

PS:
You should use task.wait() instead of wait, as it is a newer (and in my understanding better) version of said function. You have also written game.Workspace.Position, which can be written as workspace.Position.

2 Likes
local function March()
	for i, Point in pairs(WayPoints) do
		local pastOP = Point:FindFirstChild("Owner")
		if Action == "Charge" then
			print("Charge")
		elseif Point.Name == "Legionary" and pastOP != nil then
			local OwnsPoint = Instance.new("StringValue")
			OwnsPoint.Name = "Owner"
			OwnsPoint.Parent = Point
			OwnsPoint.Value = script.Parent.Name
			
			NPC:MoveTo(Point.Position)
		end
	end
end

Changed unnecessary parts.

2 Likes

This is what it prints; (as it should)
{ [1] = Legionary, [2] = Legionary, [3] = Legionary, [4] = Legionary, [5] = Legionary, [6] = Centurion, [7] = Legionary, [8] = Legionary, [9] = Legionary, [10] = Legionary, [11] = Legionary, [12] = Flag, [13] = Legionary, [14] = Legionary, [15] = Legionary, [16] = Legionary, [17] = Legionary, [18] = Standard, [19] = Action }

Edit;
The first npc moves the first time but when the formation (Position) moves, the first npc no longer moves towards it and the second npc never moves at all.

1 Like

The only real cause I see right now is your if statement. It is a rather large amount of “and” statements, are you 100% sure that it doesn’t fail while action ~= "Charge"? It would look the same as the for loop stopping (since you don’t print anywhere outside the conditions)

1 Like

I was able to fix the first npc using this script;

local NPC = script.Parent.Humanoid
local WayPoints = game.Workspace.Position:GetChildren()
local Action = game.Workspace.Position.Action
local OwnsPoint = false
local NPCNumb = game.Workspace.Position.LegionaryNumb.Value

game.Workspace.Position.LegionaryNumb.Value += 1


local function March()
	for i, Point in pairs(WayPoints) do
		if Point.Name == "Legionary" and not Point:FindFirstChild("Owner") and not OwnsPoint and Action ~= "Charge" and Point:IsA("Part") then
			local Ownspoint = Instance.new("StringValue")
			Ownspoint.Name = "Owner"
			Ownspoint.Parent = Point
			Ownspoint.Value = game.Workspace.Position.LegionaryNumb.Value
			
			OwnsPoint = true
			print(WayPoints)
			NPC:MoveTo(Point.Position)
		elseif OwnsPoint and Point.Name == "Legionary" and Action ~= "Charge" and Point:IsA("Part") then
			NPC:MoveTo(Point.Position)
		elseif Action == "Charge" then
			print("Charge")
		end
	end
end

while wait() do
	March()
end

Now the second npc also moves, but to the same exact point.

Are they sharing value, especially point?

Let me shorten.

local NPC = script.Parent.Humanoid
local WayPoints = game.Workspace.Position:GetChildren()
local Action = game.Workspace.Position.Action
local OwnsPoint = false
local NPCNumb = game.Workspace.Position.LegionaryNumb.Value--Sharing value...

game.Workspace.Position.LegionaryNumb.Value += 1


local function March()
	for i, Point in pairs(WayPoints) do
		if Action == "Charge" then
			print("Charge")
		elseif Point.Name == "Legionary" and not Point:FindFirstChild("Owner") and not OwnsPoint and Point:IsA("Part") then
			OwnsPoint = true
			
			local Ownspoint = Instance.new("StringValue")
			Ownspoint.Name = "Owner"
			Ownspoint.Parent = Point
			Ownspoint.Value = game.Workspace.Position.LegionaryNumb.Value
			print(WayPoints)
			NPC:MoveTo(Point.Position)
		elseif OwnsPoint and Point.Name == "Legionary" and Point:IsA("Part") then
			NPC:MoveTo(Point.Position)
		end
	end
end

while wait() do
	March()
end

They shouldn’t be. Each npc has it’s own script.

I made a couple of edits to the script and I also changed the names of some of the waypoints because the npc’s were getting them mixed up. But alas, now the second npc doesn’t move to the waypoint or do anything nor even print anything.

New script;

local NPC = script.Parent.Humanoid
local WayPoints = game.Workspace.Position:GetChildren()
local Action = game.Workspace.Position.Action
local ownsPoint = false
local NPCNumb = game.Workspace.Position.LegionaryNumb.Value

game.Workspace.Position.LegionaryNumb.Value += 1

local function March()
    for i, Point in pairs(WayPoints) do
        if Point.Name ~= "Centurion" and Point.Name ~= "Standard" and not Point:FindFirstChild("Owner") and not ownsPoint and Action ~= "Charge" and Point:IsA("Part") then
            Ownspoint = Instance.new("IntValue")
            Ownspoint.Name = "Owner"
            Ownspoint.Parent = Point
            Ownspoint.Value = NPCNumb

            print(Ownspoint.Value)
            print(NPCNumb)

            ownsPoint = true
            print(WayPoints)
            NPC:MoveTo(Point.Position)
        elseif ownsPoint and Point.Name ~= "Centurion" and Point.Name ~= "Standard" and Action ~= "Charge" and Point:IsA("Part") then
            NPC:MoveTo(Point.Position)
        elseif Action == "Charge" then
            print("Charge")
        end
    end
end

local function CheckNumb()
    if not ownsPoint and Ownspoint.Value ~= NPCNumb then
        print("Doesn't own this waypoint")
    elseif ownsPoint and Ownspoint.Value == NPCNumb then
        print("Owns this waypoint")
    elseif ownsPoint and Ownspoint.Value ~= NPCNumb then
        print("Owns a waypoint but not this waypoint")
    end
end

while wait() do
    March()
    CheckNumb()
end

P.s., sorry for changing the script up so many times, I’m just trying to be proactive.

CheckNumb() should be in for loop and show who outputting.

local function March()
    for i, Point in pairs(WayPoints) do
        if Point.Name ~= "Centurion" and Point.Name ~= "Standard" and not Point:FindFirstChild("Owner") and not ownsPoint and Action ~= "Charge" and Point:IsA("Part") then
            Ownspoint = Instance.new("IntValue")
            Ownspoint.Name = "Owner"
            Ownspoint.Parent = Point
            Ownspoint.Value = NPCNumb

            print(Ownspoint.Value)
            print(NPCNumb)

            ownsPoint = true
            print(WayPoints)
            NPC:MoveTo(Point.Position)
        elseif ownsPoint and Point.Name ~= "Centurion" and Point.Name ~= "Standard" and Action ~= "Charge" and Point:IsA("Part") then
            NPC:MoveTo(Point.Position)
        elseif Action == "Charge" then
            print("Charge")
        else
            print("Irriegal point. Print value.")
        end
    end
end
1 Like

Ok, I tested this code out and it prints 06:36:11.762 Irriegal point. Print value. (x300) - Server - AI:30
It also printed 1 for Ownspoint and for NPCNumb. And the Npc still moved to the point. And btw, for some reason the second npc is moving again. But still only to the same location as the first.

local function March()
    for i, Point in pairs(WayPoints) do
        if not ownsPoint and (Point.Name ~= "Centurion" and Point.Name ~= "Standard") and not Point:FindFirstChild("Owner") and Action ~= "Charge" and Point:IsA("Part") then
            IntOwnspoint = Instance.new("IntValue")
            IntOwnspoint.Name = "Owner"
            IntOwnspoint.Parent = Point
            IntOwnspoint.Value = NPCNumb

            print(IntOwnspoint.Value)
            print(NPCNumb)

            ownsPoint = true
            print(WayPoints)
            NPC:MoveTo(Point.Position)
        elseif ownsPoint and (Point.Name ~= "Centurion" and Point.Name ~= "Standard") and Action ~= "Charge" and Point:IsA("Part") then
            NPC:MoveTo(Point.Position)
        elseif Action == "Charge" then
            print("Charge")
        else
            print("Name:"..Point.Name)
            print("Action:"..Action)
            print("Class:"..Point.Class)
        end
    end
end

What will print?

I forgot the .Value after local Action = game.Workspace.Position.Action.

Well anyways, that has nothing to do with the print, so here is the error and the print statements;

Prints;
14:44:25.968 Name:Centurion - Server - AI:27
14:44:25.968 Action:Follow - Server - AI:28

Error;
14:44:25.968 Class is not a valid member of Part "Workspace.Position.Centurion" - Server - AI:29

One solved. Next is IsA(“Part”).

local className = Point.Class or Point:Class() or "None"
            print("Name:"..Point.Name)
            print("Action:"..Action)
            print("Class:"..className)

No prints this time just an error;

18:22:30.770 Class is not a valid member of Part "Workspace.Position.Centurion" - Server - AI:27 (Same error)

…Oh.

local className = Point.ClassName or "None"

If printing not works, replace IsA("Part") to IsA("BasePart") and remove printing className.

No error tis time. Printed multiple times for each child of Position that wasn’t a part. (except for centurion)

Example;
19:35:59.102 Name:LegionaryNumb - Server - AI:28,
19:35:59.102 Action:Follow - Server - AI:29,
19:35:59.102 Class:IntValue - Server - AI:30

No idea what LegionaryNumb does.

for i, Point in ipairs(WayPoints) do

Works, but the second npc (which is being created in replicated storage then moved to the workspace) is still going to the same position as the first npc.

LegionaryNumb is an int value that sets the npc’s id.

Where you cloning NPC?
That should be in inside of loop.

For right now in testing, I have just been manually duplicating the npc. I have the exact same npc inside of a folder in replicated storage that I have been adding all the script changes to also.