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.