Help optimizing client-based Enemy NPC's

Hello everyone! Please help me optimize my NPC’s. I keep lagging or getting frame rate drops whenever I get 6+ NPCs “aggroed”.

Code:

AIHandler (Local Script)
Location: game.StarterPlayer.StarterPlayerScripts

local Replicated = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Deb = game:GetService("Debris")
local ContentProvider = game:GetService("ContentProvider")

local player = game.Players.LocalPlayer
local character = workspace:WaitForChild("Characters"):WaitForChild(player.Name)

repeat task.wait() until #workspace.Map:GetChildren() >= 1

local Map = workspace.Map:FindFirstChildWhichIsA("Model")
local Enemies = Map:WaitForChild("Enemies")
local RegionFolder = Map:WaitForChild("Regions")

local OverLapParamsNew = OverlapParams.new()
OverLapParamsNew.FilterType = Enum.RaycastFilterType.Include
OverLapParamsNew.MaxParts = 30

local EnemySpawnedFolder = workspace.SpawnedEnemies

local AssetsToLoad = {workspace}
ContentProvider:PreloadAsync(AssetsToLoad)

repeat task.wait() until #Enemies:GetChildren() > 0

task.wait(3)

local Regions = RegionFolder:GetChildren()

for i, v : Part in Map:FindFirstChild("Enemies"):GetChildren() do
	if script.Parent.AIs:FindFirstChild(string.gsub(v.Name, "%d+", "")) then
		local NewEnemy : Model = Replicated:WaitForChild("Assets"):WaitForChild("Enemies"):FindFirstChild(string.gsub(v.Name, "%d+", "")):Clone()
		NewEnemy.Parent = EnemySpawnedFolder
		
		NewEnemy:PivotTo(v.CFrame)
		NewEnemy:SetAttribute("ShootCD", false)
		NewEnemy.Name = v.Name
		
		local RegionEnemyIsIn
		OverLapParamsNew.FilterDescendantsInstances = {NewEnemy}
		
		for index, region : Part in Regions do
			local partsin = workspace:GetPartBoundsInBox(region.CFrame, region.Size, OverLapParamsNew)
			
			for indexparts, PartInside in partsin do
				if PartInside.Parent == NewEnemy then

					RegionEnemyIsIn = region.Name

				end
			end
		end
		
		NewEnemy:SetAttribute("Region", RegionEnemyIsIn)
		
		require(script.Parent.AIs[string.gsub(v.Name, "%d+", "")]):AI(NewEnemy)
		table.insert(require(script.Parent.AIs[string.gsub(v.Name, "%d+", "")]).EnemiesTable, NewEnemy)
		
	end
	
end

repeat task.wait(1) until #EnemySpawnedFolder:GetChildren() < 1

print("Work")

player.PlayerGui.WinScreen.Enabled = true

Here are the AI modules for each enemy.

1 Like