Two functions with Coroutines on Heartbeat not working

  1. What do you want to achieve?

I want to have two or more functions that would normally block each other to run on a coroutine that runs every heartbeat. My previous implementation that worked was putting a while true do loop for both functions inside of a spawn function, however, using spawn function is not ideal for obvious reasons, and I heard that while true do should be avoided in favor of Heartbeat when possible.

  1. What is the issue? Include screenshots / videos if possible!

Here is the relevant code block:

-- made appropriate initializations, important ones below:		

local rate = 1 / 30
local lastRelease = 0
local timeElapsed = 0

--other local functions here including emitLightning, createcloud, and supplements to createcloud

local gc = clouds:GetChildren()
wait (1)

local function func1()
	local gc = clouds:GetChildren() 
	local angle = math.atan((-baseWind.Z * 1.2) / 400)
	local t1, t2 = wait(rate)
	if lastRelease < t2 then
		createcloud(Vector3.new(math.random(limits[1].x, limits[2].x), math.random(limits[1].y, limits[2].y), math.random(limits[1].z, limits[2].z)))
		local desiredMax = 10
		local desiredMin = 0
		local alpha = 3
		local beta = 1
		cloudsPerSecond = generatorModule.generateNumber(alpha, beta, desiredMin, desiredMax) * 2 * -((workspace.GlobalWind.Z-10)/75)
		lastRelease = t2 + 1 / cloudsPerSecond
	end
	for i, v in pairs(gc) do
		local speed = string.sub(v.Name,11)
		v.CFrame = v.CFrame + Vector3.new(0, 0, -speed * rate)
		local lightningclou = v:FindFirstChild("HasLightning")
		if lightningclou then
			if math.random() < 0.01 then 
				spawn(function()
					emitLightning(v)
				end)
			end
		end
		if v.Position.z - v.Size.Z / 2 < respawnZ then
			v:Destroy()
		end
	end
end

local function func2()
	for i=1,gustIntervals do
		local f = math.sin(math.pi * dgf * i)
		workspace.GlobalWind = baseWind + f * gust
		xwind = (baseWind + f * gust) * 1.2
		zwind = (baseWind + f * gust) * 1.2
		wait(dg)
	end
	workspace.GlobalWind = baseWind 
	xwind = baseWind * 1.2
	zwind = baseWind * 1.2
	WindChangeEvent:FireAllClients(xwind.X, zwind.Z)
	local waitbreeze = math.random()*gustCycleDelay
	wait(waitbreeze)
	gustCycleDelay = math.random(4, 10) 
	gust = Vector3.new(math.random(0, 50) - 25, 0, -math.random(0, 40))
	gustCycleDuration = math.random(3, 10)
	gustIntervals = 100
	dg = gustCycleDuration / gustIntervals
	dgf = dg / gustCycleDuration
end

game:GetService("RunService").Heartbeat:Connect(coroutine.wrap(func1))
game:GetService("RunService").Heartbeat:Connect(coroutine.wrap(func2))

There is the error: attempt to compare number < nil on the line below:

if lastRelease < t2 then
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I tried defining local lastRelease = 0 as a global, however, that did not solve the problem. Keep in mind that the code inside func1 and func2 worked when inside of a while true do loop which was then inside of a spawn function.

I think its the other way around. Last release isn’t the nil value. It’s t2 that’s nil. You can always double check if a value exist by just printing it.

e.g

print(lastRelease, t2) -- t2 should be nil in this case
if lastRelease < t2 then

As for why this code is erroring. Look to this line here:

	local t1, t2 = wait(rate)

Double check that your wait function (if its a custom one) is returning 2 values. If that’s just the default roblox wait function then it only returns 1 value (which is how much time elapse since called) and therefore t2 is nil.

Sidenote: Use task.wait() as its the most updated library and wait is deprecated.

1 Like

I solved it, I can’t coroutine with heartbeats. If someone here can explain why my two functions can run together without yielding or waiting for the other to finish with heartbeats, but my while true do loops required coroutines or spawn functions, or if this heartbeat method is having unseeable downsides compared to spawn function + while true do, I will give you the solution :grinning:

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