Is this Simple non-humanoid NPC script good enough

Hello everyone,

I made a script for my TDS game and I want to make sure it works with as much NPCs as possible

Module:

function ZombieHandler.SpawnZombie(Type)
	local Zombie = {}
	table.insert(ZombieHandler.ZombieList,Zombie)
	
	Zombie.Type = Type
	Zombie.Speed = ZombieStats.List[Type].Speed
	Zombie.Health = ZombieStats.List[Type].Health
	Zombie.Height = ZombieStats.List[Type].Height
	
	Zombie.Part = Cache:GetPart()
	Zombie.Position = 0
	Zombie.Row = math.random(0,8)

	Zombie.Part.Position = (workspace.Grass:FindFirstChild("SpawnZ"..Zombie.Row).Position -  Vector3.new(0,workspace.Grass:FindFirstChild("SpawnZ"..Zombie.Row).Position.Y,0) ) +   Vector3.new(0, GrassFolder:FindFirstChild("X0Z0").Position.Y + ZombieStats.List[Type].Height,0)
	
	Zombie.Part.Parent = workspace.Zombies
	
	setmetatable(Zombie,ZombieHandler)

	
	Zombie.ZombieMovementEvent = Zombie.Part:GetAttributeChangedSignal("Active"):Connect(function()
		Zombie:Move()
	end)


	return Zombie
end

function ZombieHandler:Move()
	self.Position += 1
	local Destination
	local End
	
	if  GrassFolder:FindFirstChild("X"..self.Position.."Z"..self.Row) then
		Destination = 	 GrassFolder:FindFirstChild("X"..self.Position.."Z"..self.Row).Position + Vector3.new(0,self.Height,0)
	else
		Destination = self.Part.Position + Vector3.new(3,0,0)
		End = true
	end
	
	local Distance = (Destination - self.Part.Position).Magnitude
	
	local Tween =  TweenService:Create(self.Part,TweenInfo.new(Distance / self.Speed,Enum.EasingStyle.Linear),{Position = Destination})
	Tween:Play()

	Tween.Completed:Once(function()
		if End then
			
			self:Kill()
		end
		self.Part:SetAttribute("Active",not self.Part:GetAttribute("Active"))

	end)



end

function ZombieHandler:Kill()
	self.Part.Color = Color3.fromRGB(163, 162, 165)
	self.ZombieMovementEvent:Disconnect()
	


	Cache:ReturnPart(self.Part)
	
	
	table.remove(ZombieHandler.ZombieList,table.find(ZombieHandler.ZombieList,self))
	print(#ZombieHandler.ZombieList)
end

a simple script that uses the said module:

for i = 1 , ZombieAmount do
		local Zombie = ZombieModule.SpawnZombie(Zombies[math.random(1,3)])
		Zombie.Part:SetAttribute("Active",true)
		print("The workspace has a total of "..#workspace.Zombies:GetChildren())
		task.wait()
end

it has around 1% activity and a rate of 60/s with 200 zombies if all the zombies are inside the field and are alive.

Is this code good enough and is there a way to optimize it further to accept more NPCs?

Thank you. :smiley:

6 Likes

It’s a nice clean written module. It does look like you are using tweens for this so you should be also looking at the tween performance.

It really depends on how many times you call the function.

There are a couple of optimisations you could try. I don’t really recommend them unless you are planning to have 1000+ zombies.

The only thing I would do (if you are not already) is make sure the tweens are rendered on the client. It only means you don’t have to replicate 200 moving objects 60 times a second.

I would like to ask though. Have you stress tested it?
Also, have to checked the memory usage?

2 Likes

Thanks for your feedback :smiley:.

as for strees testing I went as far as 1500 zombies with almost not lag and as for the memory usage how would I check it?

There are 2 main ways to test it. One is to open a game and then go into the developer console in the Roblox menu. That is the most straight forward.

You can view how much memory is taken up by things like terrain and parts.
Whilst you are there you could even have a look at the network settings. I don’t know much about what those should fall in the realm of but I do know that is you set the replication lag to 2 you should be able to test how it would feel for players with bad internet.

The next I usually use is gcinfo(). If you get the change in memory you can see how much memory is being used.

local MEMORY = gcinfo()
local TestTable = {}
for i = 1 ,20000000 do
	table.insert(TestTable,{Random.new()}) -- Add random object
end
print("Memory used:",((gcinfo() - MEMORY)/1000000),"GB")

Here is a test with 20 million random objects. As you can see it is relatively accurate.
Before:
image
After:
image
image
It is relatively accurate.

Here you can also see the usage inside the developer console.


You have to go all the way down to PlaceScriptMemory to find it.

There is apparently a service. I’ve never used it. It’s also worth a read.

Really if it runs at 1000+ then you should be quite happy. Of course I was storing millions of objects as a test. If your game suddenly jumps 2GB then it would be a serious issue in a live production version of you game. I know phones and computers are much more powerful nowadays but if you load a game on your phone and it keeps crashing then it would be the first place to look for me.

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