Using RunService.Stepped to trigger a .stepped function on all active NPCs?

Say I have a method that is inherited by all newly created NPCs, and I want to fire that every .stepped.

This method will determine targetting, determine whether to attack, whether to flee, etc.

Is this going to cause major performance issues? Like if I have 50 NPCs in the game and each of them has an ‘update’ method being triggered every .stepped, is this going to kill my game??

If so, what are the alternatives?

Performance will be strongly dependent on what you’re doing to process those actions, not necessarily the number of them - in fact it’s probably better than you’ve already thought about using one Stepped event to process your NPCs’ actions rather than multiple because you’re staying mostly in pure Luau.

More context or some code samples might help you net a better answer, unless this works as one.

I just mocked up this code to give a rough example of some of the stuff I’d be running, sorry if there’s some issues with the code.

function AISpawner.new()
	local self = {}
	self.instance = _newDemon()
	self.timeOfSpawn = os.time()
	self.linkedSpawn = nil
	self.currentTarget = nil
	self.currentGoal = nil
	self.moveTo = nil
	setmetatable(self, AISpawner)
	return self
end

function AISpawner:OnStepped()
	if (os.time() - self.timeOfSpawn > 70) then -- AI has been alive too long
		self:cleanup()
		return
	end
	
	if (self.currentGoal == nil) and (self.currentTarget == nil) and (self.moveTo == nil) then
		
		local destinationPos = workspace.DestinationPosition
		self.instance.Humanoid:MoveTo(destinationPos)
		
		self.moveTo = self.instance.Humanoid.MoveToFinished:Connect(function()
			print("Finished moving!")
			self.moveTo:Disconnect()
			self.moveTo = nil
		end)

	end
end

You’re fine with this amount of code: you’re just calling a method and connecting an event if certain conditions are met. These aren’t expensive to execute. You might start seeing instances of “lag” if your OnStepped method includes anything computationally expensive or yields and isn’t being pseudothreaded (e.g. not using task library or coroutines to call OnStepped).

So I should be calling the method on a separate thread? Every single NPC gets their method called on a separate thread per .stepped?

No, not necessary.

Your OnStepped function right now does not pass the “if”. You don’t need to.

1 Like