Client script sometimes ignores loop

Hello!

I’m working on some fun collection service stuff to automatically convert parts to certain models depending on a tag they have to make placement easier, but sometimes when playtesting, the code just goes past the i, v loop.

Here’s a look at what’s happening when the script fails:
image
image

Here’s what’s supposed to happen:
image
image

When the script “fails”, there aren’t any errors output in the console, so I’m really unable to pinpoint where the script is going wrong, whether it be a problem with the script or just a Roblox thing.

Here’s my code, local script in StarterGui:

local collectionService = game:GetService('CollectionService')
local replicatedStorage = game:GetService('ReplicatedStorage')

local springIncrement = 2

print('running: '.. script:GetFullName())

for i, object in pairs(collectionService:GetTagged('spring')) do
	print('sproing!')
	local newSpring = replicatedStorage.spring:Clone()
	newSpring:SetPrimaryPartCFrame(object.CFrame)
	newSpring.Parent = workspace
	object:Destroy()

	local bumper = newSpring:WaitForChild('bumper')
	local spring = newSpring:WaitForChild('spring')

	newSpring.Positioner:Destroy()

	bumper.Touched:Connect(function(hit)
		if game.Players:GetPlayerFromCharacter(hit.Parent) and not newSpring:HasTag('springActive') then
			collectionService:AddTag(newSpring, 'springActive')
			local origBumperPos = bumper.Position
			local origSpringPos = spring.Position
			local origSpringSize = spring.Size

			bumper.Position += Vector3.new(0,springIncrement,0)
			spring.Size += Vector3.new(0,0,springIncrement)
			spring.Position += Vector3.new(0,springIncrement/2,0)
			bumper.Material = Enum.Material.Neon
			spring.Material = Enum.Material.Neon

			local hrp = hit.Parent.HumanoidRootPart :: Part
			local sound = script.spring
			
			sound.PlaybackSpeed = Random.new():NextNumber(0.9, 1.3)
			sound:Play()

			-- EFFECT --
			local bodyVel = Instance.new('BodyVelocity')
			bodyVel.Velocity = Vector3.new(0,100,0)
			bodyVel.MaxForce = Vector3.new(100000,100000,100000)
			bodyVel.P = math.huge
			bodyVel.Parent = hrp

			game:GetService('Debris'):AddItem(bodyVel, 0.1)

			task.delay(0.2, function()
				bumper.Position = origBumperPos
				spring.Size = origSpringSize
				spring.Position = origSpringPos
			end)

			task.delay(0.4, function()
				spring.Material = Enum.Material.Plastic
				bumper.Material = Enum.Material.Plastic
				collectionService:RemoveTag(newSpring, 'springActive')
			end)
		end
	end)
end

print('finished!')

Any help would be appreciated! As much as the script works most of the time, I would rather it works all of the time.

1 Like

I’ve identified a problem causing this script to not run: sometimes the ‘spring’ tag just doesn’t apply to parts.

Found a solution. Just had to add a repeat wait() until game:IsLoaded() before running the pairs function.

Is the “spring” tag being applied to the objects during runtime (via a Server script) or did you manually apply it to each object while editing the game (not while playtesting)?


Consider moving the code within the loop into a function and then activating it in two separate ways:

  • From a loop that goes through every object that already has that tag at the time the LocalScript code runs (which is what is currently on line 8 from the codeblock you posted).

  • In addition to being activated every time the CollectionService:GetInstanceAddedSignal() event fires.

This should make sure that if none of the objects are tagged at the time the loop initially runs, the event will detect when new objects are applied that tag in the future so the relevant code will run as intended.

Example Revision

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local springIncrement = 2

local function springFunctionality(object)
    -- Code that was initially in the loop goes here
end

CollectionService:GetInstanceAddedSignal("spring"):Connect(springFunctionality)

for index, object in CollectionService:GetTagged("spring") do
    print("Total iterations of the loop: "..tostring(index))
    springFunctionality(object)
end

Edit (mid-draft): Was about to post my reply and then I saw you marked a solution

I would not recommend utilizing this in the case that more objects are tagged over time as that would not guarantee with 100% certainty that the LocalScript correctly identifies every object that is meant to have the “spring” tag. (*Edit: Especially in the case that the springs could be spread out over a large distance and StreamingEnabled is turned on, the further objects may not be streamed in yet, and because the loop would only run once, it may not update those further objects without listening for the tag to be applied to objects during runtime).

1 Like

The spring tags were manually added outside of playtesting. I really appreciate your solutions, though. I’ll definitely work on implementing those.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.