Will this code create non-stopping loops

So I made an AI system which controls up to 20 bots movement and actions. But for some reason the more active they are the higher script acitivity gets (80%+) and the rate also gets to like 200,000. I’m suspecting it has something to do with never ending loops but not sure. I’m gonna post a example script of how the system works.


-- services --

local replicatedStorage = game:GetService('ReplicatedStorage')

-- constants --

local bots = workspace.Bots
local botsDataHolder = replicatedStorage.BotsDataHolder

local function moveBot(bot)
	-- here is some VectorForce movement code that runs once when the function is called --
end

local function attackTarget(bot, data)
	local target = data.Target
	local otherTaskAction = data.OtherTaskAction
	
	repeat task.wait(0.1)
		if target.Value == '' then break end -- if there's no target for some reason then break the loop
		if otherTaskAction.Value == true then break end -- if there's a more important task then also break the loop
		moveBot(bot) -- calls the "moveBot" function
	until (bots[target.Value].Position-bot.Position).Magnitude < 10 -- stops the loop if bot gets close enough to the target
end

local function otherTaskExample(bot, data)
	local target = data.Target
	local otherTaskAction = data.OtherTaskAction
	local assignedTaskObjective = false
	
	repeat task.wait(0.1)
		if target.Value ~= '' then break end -- in case the bot gets assigned another task that is more important it'll break the loop
		-- do stuff --
	until assignedTaskObjective == true -- example
end

local function assignTask(bot, data)
	local target = data.Target
	local otherTaskAction = data.OtherTaskAction
	
	-- how I would make the bot do stuff --
	
	if bots:FindFirstChild(target.Value) then
		coroutine.wrap(attackTarget)(bot, data) -- wraps the function inside of a coroutine so all of the bots can work at the same time
	end
end

bots.ChildAdded:Connect(function(bot) --  gets the bot's character 
	local data = botsDataHolder[bot.Name] -- this data stays the same even after the bot dies
	local target = data.Target
	local otherTaskAction = data.OtherTaskAction --[[this is just an example of other tasks that the bot could have assigned, which would also interrupt attackTarget function
	because it would run another couratine.wrap(function) with a loop inside of it, however I try to make it not do that by breaking the loops or returning the functions]]
	target.Changed:Connect(assignTask)(bot, data) -- calls a function to make the bot do something when the bot finds a new target
	otherTaskAction.Changed:Connect(assignTask)(bot, data) -- calls a function to make the bot do something when the bot is targeted by another bot

	-- this is where I set the "Target" value based on the magnitude and how the bot knows when it's supposed to do something --
	
	while task.wait(0.1) do
		for _, otherBot in pairs(bots:GetChildren()) do
			if otherBot.Name ~= bot.Name then 
				if target.Value == '' then 
					if (otherBot.Position - bot.Position).Magnitude < 100 and target.Value ~= otherBot.Name then 
						target.Value = otherBot.Name
					end
				end
			end
		end
	end
end)


This is rougly how it works, not sure if I made some stupid mistake, I just wrote this example script. I
have tried a lot of stuff to resolve the issue but none of it helped, I tried putting all of the functions inside of CharacterAdded event but that didn’t help at all. Every bit of help is very appreciated.

1 Like

Have you tried converting your AI to a Class?

Here is a tutorial:

I don’t think OOP would help me much with moving the bot’s movement logic but thanks

What do you mean by Active Exactly ?

Basically the script is running too much code at once that it causes the server to crash after some time

Fixed the issue, it had something to do with if statements. Basically the loop is supposed to stop if the bot dies but I did not check it correctly:

if not bot then return end

Because the bot still exists inside of nil so what I did to fix it was:

if bot.Parent == nil then return end 
-- you could also do this 
if bot.Parent ~= botsFolder then return end

Did you use Dictionaries to solve it? (just curious)

I’ve used a table to store some important data, like if the bot already has an assigned task and such but that’s about it