FastSpawn completely stops at wait()?

local FastSpawn = require(game.ReplicatedStorage.FastSpawn)

local a = -- path to a part

FastSpawn(function()
		while true do
			wait() -- Added this to test and the thread stops here.
			print(1)
			for i=1,30 do a.Transparency = a.Transparency+0.01 wait(0.01) end
			for i=1,30 do a.Transparency = a.Transparency-0.01 wait(0.01) end
		end
	end)
--@module FastSpawn
return function(func, ...)
	assert(type(func) == "function")

	local args = {...}
	local count = select("#", ...)

	local bindable = Instance.new("BindableEvent")
	bindable.Event:Connect(function()
		func(unpack(args, 1, count))
	end)

	bindable:Fire()
	bindable:Destroy()
end

It prints no error.

EDIT: It looks like it works on a normal part, but why not on a instance.new part?

function CreateSmoke(Pos, Stage)
	local a = Instance.new("Part",Stage)
	a.Name = "Smoke"
	a.Shape = Enum.PartType.Ball	
	a.Anchored = true
	a.CanCollide = false
	a.Size = Vector3.new(15,15,15)
	a.BrickColor = BrickColor.new("Dark stone grey")
	a.Position = Pos
	a.TopSurface = Enum.SurfaceType.Smooth
	a.Transparency = 0.1
	FastSpawn(function()
		while true do
			for i=1,30 do a.Transparency = a.Transparency+0.01 wait(0.01)  end -- Thread stops here at wait(0.01)
			for i=1,30 do a.Transparency = a.Transparency-0.01 wait(0.01) end
		end
	end)
end

Why not just use TweenService? It has a reverse parameter too.

Hmm, good suggestion. I forgot tween was a thing.

I can’t replicate the same behavior, your code seems to work as expected for me in studio.

But you might find coroutines really helpful for running code synchronously. The technique you’re using works fine, but this might simplify future development.