Bizarre thread/while loop behavior

I have something really strange going on here. I have a weapon, that when it fires, the library generates an impact mark on whatever the projectile hits. Now this works for one weapon. A different weapon, it seems the script is getting hung up at the while statement. Consider the following code fragment:

	-- Fade out if requested.
	if effects.fade == true then
		local thread = task.spawn(function()
			print("Fade")
			local decal = mark.Decal
			local steps = effects.duration / 0.1
			local transStep = 1 / steps
			local trans = 0
			print(steps, transStep, trans)
			while trans <= 1.0 do
				decal.Transparency = math.floor(trans * 100) / 100
				trans += transStep
				task.wait(0.1)
				print(trans)
			end
			print("Loop Done")
			mark:Destroy()
		end)
		delay(10, function()
			print(coroutine.status(thread))
		end)
		--debrisService:AddItem(mark, effects.duration + 0.1)
	else
		debrisService:AddItem(mark, effects.duration)
	end

The print and delay statements are there for me to see what’s happening. The parameters that it’s working with are as follows:

			impactTarget = {		-- Displays a decal on the target at the
				-- point of impact.
				imageType = enums.ImpactImageType.Scorch;
				duration = 10;		-- Time for the mark to live.
				fade = true;		-- Fade mark out during life.
				player = false;		-- Create on person
				playerDead = false;	-- Create on player if they are dead.
				world = true;		-- Create on world
			};

The effects variable in the routine gets set to the impactTarget table.

Now, on the problem weapon, trans counts to 0.45000000023 then stops. “Loop Done” never prints. If I place the print statement before mark.Transparency, it stops at 0.44000000002. It’s interesting to note that the print statement inside the delay never executes either. Between both weapons, the parameters going into the loop are the same, yet one works and the other doesn’t.

The only real difference is that with the one that works, it is called from the actual weapon firing code. The one that doesn’t is called from the projectile touched event. Now it shouldn’t matter but does it matter?

Since the delayed print never prints, that’s telling me that something is going on with the thread itself. But I have no idea what. This is the code without all the debugging statements if it helps.

	-- Fade out if requested.
	if effects.fade == true then
		task.spawn(function()
			local decal = mark.Decal
			local steps = effects.duration / 0.1
			local transStep = 1 / steps
			local trans = 0
			while trans <= 1.0 do
				decal.Transparency = trans
				trans += transStep
				task.wait(0.1)
			end
		end)
		debrisService:AddItem(mark, effects.duration + 0.1)
	else
		debrisService:AddItem(mark, effects.duration)
	end

The workaround is setting fade to false. I may do that because I don’t want threads hanging around and chewing up server resources. Could the while statement be somehow crashing the LUA interpreter internally? Seems strange that the spawned thread, and the parent thread, just seems to stop. Other than what I have suggested, does anyone have any ideas as to what is going on and how to fix it?

EDIT: I forgot to mention, when I remove the 0.1 from task.wait so it looks like task.wait(), the loop runs all the way through and completes.