Weird `:GetDescendants()` behaviour with for loop

Hello forum,
I’ve ran into this issue (could be a bug or just I am doing it wrong so I am using the scripting support tag) :

print(#self.Model:GetDescendants())
for i, instance in self.Model:GetDescendants() do
	print(i)
end

The output to this code is →

  13:28:07.610  87  -  Server - Tycoon:71
  ...
  13:28:07.627  76  -  Server - Tycoon:73
  13:28:07.627  77  -  Server - Tycoon:73
  13:28:07.627  78  -  Server - Tycoon:73
  13:28:07.627  79  -  Server - Tycoon:73
  13:28:07.628  80  -  Server - Tycoon:73
  13:28:07.628  81  -  Server - Tycoon:73
  13:28:07.628  82  -  Server - Tycoon:73

Why is it that with loop it only gets to 82? I need it to loop thru the whole :GetDescendants(). If you need any more information, please ask below

Are you running this code on the client? There’s a possibility that the code is running before everything in that model has loaded on the client.

I am running this on The server. Even after adding like wait(5), the output is the same.

Could you show a picture of the descendants?


They are mostly models which contain meshparts or just parts.
This is how I discovered the bug, I was adding new models but the code couldn’t find them

You’re using self, where did you put the code in? Without seeing the other part of your code it looks normal.

The code runs from ServerScriptService as a server script. It creates the new self object for every player in .PlayerAdded event. Than it calls this function →

function Tycoon:LockAll()
	print(#self.Model:GetDescendants())
	for i, instance in self.Model:GetDescendants() do
		print(i)
		if CollectionService:HasTag(instance, "Unlockable") then
			self:Lock(instance)
		else
			self:AddComponents(instance)
		end
	end
end

Which not long ago started this weird behaviour where it wouldn’t "Lock" the parts even if they had the "Unlockable" tag, that’s why i tried to see where the problem is and it seems that it doesn’t loop thru all the parts which I gave screenshot in previous reply.
If I print instance, there is no Test Model which is in the screenshot in the previous post.

Is anything modified that could cause any issues while the code’s running? Note that you can also use print(instance.Name) or something similar to find out which instances aren’t reporting properly.

I don’t think anything is modifided while code’s running. All those models are there in studio. It doesn’t see Test or any part added with the tag. Although when I add a part, the
print(#self.Model:GetDescendants()) changes.

Try editing those parts with the tag to see if it changes anything, I don’t know what exactly to do from there, but it’d be helpful to see what happens.

function Tycoon:LockAll()
	for i, instance in self.Model:GetDescendants() do
		if instance.Name == "Canon1" or instance.Name == "Test" then
			print(instance.Name, 0)
		end
end

Output →

15:47:27.702  Canon1 0  -  Server - Tycoon:74

Where both Test and Canon1 are in the descendats. Having print self.Model:GetDescendants(), you can find both.

As a test, can you get descendants and store it in a variable, then print # for the amount and then loop through it?

Already tried it, didn’t work. What works is this :

function Tycoon:LockAll()
	for x, y in ipairs(self.Model:GetDescendants()) do
		if y.Name == "Test" then
			print(1)
		end
	end
	for i, instance in ipairs(self.Model:GetDescendants()) do
		if instance.Name == "Test" then
			print(2)
		end
		if CollectionService:HasTag(instance, "Unlockable") then
			self:Lock(instance)
		else
			self:AddComponents(instance)
		end
	end
end

This prints 1 but still not 2 even its excatly the same thing…
I will just try to rewrite the whole loop and see…