Stack overflow randomly?

So im making a tds game by gnomecode series and i came into an issue when placing the tower it all freezes puts this error


and places tower. Tower of course doesnt shoot.

Any idea why this might be it?

Full functions of the errors.

this is the gamecontroller. Rest is tower module.

userinputservice.InputBegan:Connect(function(input, processed)
	if processed then 
		return

	end

	if TowerToSpawn then
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
			local placedtower=	spawnTowerFunction:InvokeServer(TowerToSpawn.Name, TowerToSpawn.PrimaryPart.CFrame)
			if placedtower then
				placedtowers +=1
				RemovePlaceholderTower()
				toggleTowerInfo()
			end
			else
				RemovePlaceholderTower()
			end
		elseif input.KeyCode == Enum.KeyCode.R then
			rotation +=90
		end
	elseif hoveredInstance and input.UserInputType == Enum.UserInputType.MouseButton1 then
		local model = hoveredInstance:FindFirstAncestorOfClass("Model")

		if model and model.Parent == workspace.Towers then
			SelectedTower = model
		else
			SelectedTower = nil
		end
		toggleTowerInfo()
	end
end)
local maxTowers = 15
local tower = {}
local map= game.Workspace:WaitForChild("Grassland")
function tower.FindTarget(newTower, range, mode)
	local bestTarget = nil
	local bestWaypoint = nil
	local bestDistance = nil
	local basehealth = nil


	for i, mob in ipairs(workspace.Mobs:GetChildren()) do
		local distanceToMob = (mob.HumanoidRootPart.Position - newTower.HumanoidRootPart.Position).Magnitude
		local distanceToWaypoint = (mob.HumanoidRootPart.Position - map.Waypoints[mob.MovingTo.Value].Position).Magnitude

		if distanceToMob <= range then
			if mode == "First" then
				if not bestWaypoint or mob.MovingTo.Value >= bestWaypoint then
					if bestWaypoint and mob.MovingTo.Value > bestWaypoint then
						bestDistance = nil
					end

					if not bestDistance or distanceToWaypoint < bestDistance then
						bestDistance = distanceToWaypoint
						bestWaypoint = mob.MovingTo.Value
						bestTarget = mob
					end
				end
			end
		end
	end

	return bestTarget
end
function tower.Spawn(player ,name, cframe, previous)
	local plr = player
	wait()
	local allowedToSpawn = tower.CheckSpawn(player, name, previous)

	if allowedToSpawn then

		local newTower
		if previous then
			previous:Destroy()
			newTower = replicatedstorage.Towers.Upgrades[name]:Clone()
		else
			newTower = replicatedstorage.Towers[name]:Clone()
			player.PlacedTowers.Value += 1
		end

		local ownerValue = Instance.new("StringValue")
		ownerValue.Name = "Owner"
		ownerValue.Value = player.Name
		ownerValue.Parent = newTower.Config

		local targetMode = Instance.new("StringValue")
		targetMode.Name = "TargetMode"
		targetMode.Value = "First"
		targetMode.Parent = newTower.Config

		newTower.HumanoidRootPart.CFrame = cframe
		newTower.Parent = workspace.Towers


		for i, object in ipairs(newTower:GetDescendants()) do
			if object:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(object, "Tower")
			end
		end

		player.Cash.Value -= newTower.Config.Price.Value

		if newTower.Config:FindFirstChild("Cash") then
			player.farms.Value += 1
		end

		coroutine.wrap(tower.Attack)(newTower, plr)
		return newTower
	else
		print("Not allowed")
		return false
	end
end
1 Like

What are the lines that the error message is referring to? Stack overflow usually means you have a recursive function that’s not terminating.

1 Like
local placedtower=	spawnTowerFunction:InvokeServer(TowerToSpawn.Name, TowerToSpawn.PrimaryPart.CFrame)
coroutine.wrap(tower.Attack)(newTower, plr)
for i, mob in ipairs(workspace.Mobs:GetChildren()) do
1 Like

It seems like something inside tower.Attack is calling tower.FindTarget too much, what’s going on in that function?

1 Like

I think i might know now. The cooldown might be wrong positioned.

function tower.Attack(newTower, plr)
	local config = newTower:WaitForChild("Config")

	local target = tower.FindTarget(newTower, config.Range.Value, config.TargetMode.Value)

	if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health >= 0 then
		tower.FaceTarget(newTower,target, 0.01)

		animatetowerevent:FireAllClients(newTower, "Attack", target)


		local speedbf
		if target then
			speedbf = target:FindFirstChild("Humanoid").WalkSpeed
		end
		wait()
		if newTower.Config:FindFirstChild("Stun") then
			if target then
				target:FindFirstChild("Humanoid").WalkSpeed = 0
				wait(2)
				if target then
					target:FindFirstChild("Humanoid").WalkSpeed = speedbf
				else

				end
			end
		end
		if target then
			target.Humanoid:TakeDamage(config:WaitForChild("Damage").Value)
		end
		for _, plr in pairs(game.Players:GetPlayers()) do
			plr.Cash.Value += config.Damage.Value
		end

	

		wait(config.Cooldown.Value)
	end	
	
	if newTower and newTower.Parent then
		tower.Attack(newTower, plr)
	end

end
1 Like

That sounds right, if the if block is skipped then the function immediately calls itself again, which will lead to a stack overflow.

1 Like

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