Heartbeat doesn't wait for called functions to finish

Hey. I’m trying to code a basic AI for my game and i’m using RunService Heartbeat for main loop. I will put some part of my code in here but when i call for example returnToBase() function inside of heartbeat connection, it’s not waiting for returnToBase finish their job and call it over and over. I tried to debug it but i couldn’t get any solution.

--Function to returning to base
local function returnToBase()
	--check distance to base
	local distanceToBase = (mob.HumanoidRootPart.Position - originPos).Magnitude
	--do wee need to return to base?
	if distanceToBase > patrolRadius + 1 then
		returningToBase = true
		--make it faster until return
		mob.Humanoid.WalkSpeed = mobDb.walkSpeed * 2
		local newPos = getRandomPointInCircle()
		--Wait until it's returns to base
		while (mob.HumanoidRootPart.Position - newPos).Magnitude > 5 do
			mob.Humanoid:MoveTo(newPos)
			wait(0.2)
		end
		--mob can start patrolling again with decreased walkspeed
		targets = {}
		mob.Humanoid.WalkSpeed = patrolWalkSpeed
		returningToBase = false
	end
end

--Main loop for AI
local heartBeatConn
heartBeatConn = RunService.Heartbeat:Connect(function()
	--Target to attack
	local currTarget = nil
	--Define the behavior | if it's aggro and there is no target
	if aggro and #targets == 0 then
		currTarget = findEnemy()
	end
	--if there is targets at the table choose closest one
	if #targets > 0 then
		local closest = 999
		for index, target in pairs(targets) do
			local distance = (target.HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude
			if isAttackable(target,index) then
				if distance < closest then
					closest = distance
					currTarget = target
				end
			end
		end
	end
	--if founded a valid target then
	if currTarget then
		warn("Attack function called",currTarget.Name)
		attack(currTarget)
	else
		warn("Base return called!",currTarget)
		returnToBase()
	end
end)

That’s how Heartbeat works. Heartbeat is called at the end of every frame after physics simulation, it’s not supposed to wait until any developer code finishes executing. Consider creating your own boolean flag to prevent this that’s set to true when called and false when finished.

-- Declare it
local isReturningToBase = false

-- Set it at the top of returnToBase if it's not active
if isReturningToBase then return end
isReturningToBase = true

-- And set it to false when it's not active
isReturningToBase = false
2 Likes