Is there a better performance option for RunService.Stepped

Hi, its my first time making an enemy AI and i’ve got a problem that i’ll end up running into in the future, i have this script that uses RunService.Stepped to find the closest player, it works well but there are going to be a lot of enemies and it eventually builds up and lags the game, so i was wondering if they is a different option or a solution i can do.
here is my code

–Calling Module
local EnemyConfig = require(script.Parent.EnemyConfig)

–Services
local Players = game:GetService(“Players”)
local RunService = game:GetService(“RunService”)

–Variables
local Enemy = script.Parent
local EnemyHumanoid = Enemy.Humanoid
local EnemyHumanoidRootPart = Enemy.HumanoidRootPart

–ModuleVariables
local Health = EnemyConfig.Health
local WalkSpeed = EnemyConfig.WalkSpeed
local JumpPower = EnemyConfig.JumpPower

local Damage = EnemyConfig.Damage
local FollowDistance = EnemyConfig.FollowDistance
local RespawnTime = EnemyConfig.RespawnTime

local Range = EnemyConfig.Range

local Gold = EnemyConfig.Rewards.Gold
local EXP = EnemyConfig.Rewards.EXP

–AssigningStats
EnemyHumanoid.MaxHealth = Health
EnemyHumanoid.Health = Health
EnemyHumanoid.WalkSpeed = WalkSpeed
EnemyHumanoid.JumpPower = JumpPower

local function MoveEnemy()
local Target = nil
local PlayersInGame = Players:GetPlayers()
for _,Player in pairs(PlayersInGame) do
local Character = Player.Character

	if Character then
		local CharacterHumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
		
		if CharacterHumanoidRootPart  and (EnemyHumanoidRootPart.Position - CharacterHumanoidRootPart.Position).Magnitude < Range then
			if Target then
				if (EnemyHumanoidRootPart.Position - Target.Position).Magnitude > (EnemyHumanoidRootPart.Position - CharacterHumanoidRootPart.Position).Magnitude then
					Target = CharacterHumanoidRootPart
				end
			else
				Target = CharacterHumanoidRootPart
			end
		end
	end
end
if Target then
	EnemyHumanoid:MoveTo(Target.Position)
end
print(Target)

end

RunService.Stepped:Connect(MoveEnemy)

okay i don’t know why all the code didn’t go into the textbox but you can see all of it, this is my first post so sorry if it isn’t good

for moving; you could use a while loop and
find the closest player and move towards them and wait a bit

for ex.

while true do
   local closestTarget = getClosestTarget()
   if closestTarget then
      humanoid:MoveTo(closestTarget.Position)
   end
   task.wait(.1)
end

this ensure’s you arent doing this action twice at the same time
and if needed you can yield longer for different actions

i did try this but it ended up making the enemy’s movement be a bit delayed

oh wait i get what you mean now, i’ll give it a shot and let you know if it works

define delayed

take longer to start walking towards something?

yeah if i were to quickly walk behind it would take the second to walk to you, it isn’t too bad but it doesn’t look very good when playing the game

you could use a combination of render stepped for detecting players and then a while loop for movement

for ex. on render step check for players, if you find a player, disconnect the renderstep and start a walking while loop that will eventually reconnect the renderstep function

Instead of having a script for each enemy, you could create one script that has a table of all the enemies, then use one connection that loops through each enemy and moves it.

Edit: The performance issue is not from RunService.Stepped, but from the multiple connections to it.

i’ve never used renderstep but i could give it a shot, i’m currently trying out this other idea first

yeah that would probably work but i’m not the greatest at scripting and it sounds a bit complex for me, how would i signal to a certain enemy? i’ll give it a shot since it sounds like it would run the best out of all the other options i’ve been given also there will be multiple enemies with the same name, that shouldn’t cause a problem since its in a table right?

If you use a for loop on the table, you will be given an index, and a value. The value is the enemy.

local EnemyTable = {}
table.insert(EnemyTable, enemy)

for index, value in pairs(EnemyTable) do
    -- index is the current iteration
    -- value is the current enemy
end

You can find a specific enemy in the table using table.find.


Correct, that won’t cause any problems.

1 Like

okay its kind of working now, i’ve got it from here thank you for your help

1 Like

okay yeah your idea worked, it runs perfectly fine now thank you for your help gangy, couldn’t have done it without you

1 Like

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