In pairs loop breaking early for no reason?

I have been having this problem for a while now, but i dont know why its happening.
so basically, this is for a gun script, and RayInfo is a table in which it includes all the gun’s pellet data. When i try to loop through the table, the in pairs loop breaks early for some reason.
It seems like the reason this is happening is because either TargetPart, TargetPosition, TargetNormal, or DamageToDeal equals nil, causing it to break.

Is this a roblox glitch?

-- in the local script
for i=1, numberOfPellets do
table.insert(rayInfo, {
	['TargetPart'] = targetPart2;
	['TargetPosition'] = targetPosition2;
	['TargetNormal'] = targetNormal2;
	['DamageToDeal'] = damageAmount
})
end

--later, in the server script...



print(#RayInfo) -- Prints 6, for 6 pellets in RayInfo, which is correct.

for _, v in pairs(RayInfo) do
print("LOOPED") -- Only prints this 4 times in the output, not 6
	local distanceFromPart = (v['TargetPart'].Position - player.Character.Head.Position).Magnitude
	if (distanceFromPart > antiExploitCertainMaxRange * 1.5) or (distanceFromPart > antiExploitCertainMaxRange * 1.5) then
		print("RETURNED FIRST CHECK") -- Doesn't print at all
		return				
	end
	if v['TargetPart']:IsDescendantOf(workspace.Enemies) then
		if (determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage * IMPORTANTSERVERDATA.HEADSHOT_MULTIPLIER_GUN) or (not determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage) then
			print("RETURNED SECOND CHECK") -- Doesn't print at all
			return					
		end
	end
end

Your return statements will exit the entire loop. You can use continue instead, which will cancel the pass of the loop and resume again at the top.

1 Like

Hello!
Didn’t knew about ‘Continue’
How it works or what it can be used for?

okay, i just tried it, but the loop still breaks. Did you mean to use continue in place of return?

it always breaks as soon as v[‘TargetPart’] equals nil.

for _, v in pairs(RayInfo) do
print(v['TargetPart']) -- when this prints nil, the loop stops.
print("LOOPED") -- Only prints this 4 times in the output, not 6
	local distanceFromPart = (v['TargetPart'].Position - player.Character.Head.Position).Magnitude
	if (distanceFromPart > antiExploitCertainMaxRange * 1.5) or (distanceFromPart > antiExploitCertainMaxRange * 1.5) then
		print("RETURNED FIRST CHECK") -- Doesn't print at all
		return				
	end
	if v['TargetPart']:IsDescendantOf(workspace.Enemies) then
		if (determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage * IMPORTANTSERVERDATA.HEADSHOT_MULTIPLIER_GUN) or (not determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage) then
			print("RETURNED SECOND CHECK") -- Doesn't print at all
			return					
		end
	end
end

Continue will stop a loop, and return it at the top again. For example, this code would only print the odd numbers 1-10:

for i = 1, 10 do
	if i % 2 == 0 then -- if even
		continue -- returns to top of loop, not running `print(i)`
	end
	print(i)
end
2 Likes

Yes, replace return with continue.

Are you getting any errors though? I missed this the first time I read your question, but if your print statements just before the returns aren’t printing, then the return might not be the issue here. An error will stop your code. If v['TargetPart'] returns nil, then v['TargetPart']:IsDescendantOf(workspace.Enemies) will certainly error.

1 Like

it is printing no errors. i think you are correct with it erroring if v[‘TargetPart’] equals nil when i do:

v['TargetPart']:IsDescendantOf(workspace.Enemies)

since v[‘TargetPart’] doesn’t exist, but i changed it to

if v['TargetPart'] and v['TargetPart']:IsDescendantOf(workspace.Enemies) then

and it still breaks early.

okay i just found the solution, but am still confused why it works like this.
I did:

for _, v in pairs(RayInfo) do
print("LOOPED") -- Prints all 6 times finally
if v['TargetPart'] then -- solution
	local distanceFromPart = (v['TargetPart'].Position - player.Character.Head.Position).Magnitude
	if (distanceFromPart > antiExploitCertainMaxRange * 1.5) or (distanceFromPart > antiExploitCertainMaxRange * 1.5) then
		print("RETURNED FIRST CHECK") -- Doesn't print at all
		return				
	end
	if v['TargetPart']:IsDescendantOf(workspace.Enemies) then
		if (determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage * IMPORTANTSERVERDATA.HEADSHOT_MULTIPLIER_GUN) or (not determineIfGotHeadshot(v['TargetPart']) and v['DamageToDeal'] > antiExploitCertainShootDamage) then
			print("RETURNED SECOND CHECK") -- Doesn't print at all
			return					
		end
	end
end
end

the reason im still confused is because when i didnt have “if v[‘TargetPart’] then”, it didn’t error when i did “local distanceFromPart = v[‘TargetPart’].Position” or when i did “if v[‘TargetPart’]:IsDescendantOf(workspace.Enemies) then”, it just broke out of the loop, not erroring at all.

1 Like

btw i didnt know about continue, thanks for the help Gnarwhal :ok_hand: ,

1 Like