Optimization of monster spawning

Good afternoon everyone, this is the first time my question is not from the “nothing works” category. I would like to improve my understanding of code optimization, so maybe someone has some tips on how to make this code better ?


function Spawn(self, monsterName)
	if monsterName == "ogre" then
		factory.create("main#monster_ogre", vmath.vector3(800, 200, 1), nil ,{damage = ogre_stats.damage, speed = ogre_stats.speed, hp = ogre_stats.hp, height = ogre_stats.height, experience = ogre_stats.experience}, nil)
	elseif monsterName == "slaad" then
	elseif monsterName == "harpy" then
	elseif monsterName == "mushroom" then
	elseif monsterName == "giant" then
end

function mobSpawn(self, wavePoint)
	local monster = {"slaad", "ogre", "harpy", "mushroom", "giant"}
	while(wavePoint > 0) 
	do
		if wavePoint >= 5 then 
			local numMonster = math.random(1, 5)
			wavePoint = wavePoint - numMonster
			Spawn(self, monster[numMonster])
			print(monster[numMonster])
		else
			local numMonster = math.random(1, wavePoint)
			wavePoint = wavePoint - numMonster
			print(monster[numMonster])
		end
	end
end

My first thought would be to create a more elaborate lua table of monsters & their attributes.

You’d still randomly choose one of the monsters, but pass the nested data to your Spawn function.

I’d move it outside of the functions also, so that it doesn’t have to be recreated each time they are called.

Something like this:

local monster = {
  "slaad" = {
    factory_url = "main#monster_slaad",
    damage = 10,
    speed = 5,
    hp = 75,
    height = 1.5
    experience = 5
  },
  "ogre" = {...},
  "harpy" = {...},
  "mushroom" = {...},
  "giant" = {...}
}

function Spawn(self, monster, position)
  factory.create(monster.factory_url, position, nil, { damage = monster.damage, ...})  
end
6 Likes

Thank you very much!

My realisation:

--Monster_stats
local monster = {
	slaad = {factory_url = "main#monster_slaad" ,damage = 10, speed = 1.0, hp = 100, height = 125, experience = 15, point = 1},
	ogre = {factory_url = "main#monster_ogre", damage = 10, speed = 1.0, hp = 100, height = 125, experience = 15, point = 2},
	harpy = {factory_url = "main#monster_harpy", damage = 10, speed = 1.0, hp = 100, height = 125, experience = 15, point = 3},
	mushroom = {factory_url = "main#monster_mushroom", damage = 10, speed = 1.0, hp = 100, height = 125, experience = 15, point = 4},
	giant = {factory_url = "main#monster_giant", damage = 10, speed = 1.0, hp = 100, height = 125, experience = 15, point = 5},
}

local monster_list = {"slaad", "ogre", "harpy", "mushroom", "giant"}

local position = vmath.vector3(800, 200, 1)

function mobSpawn(self, wavePoint)
	while(wavePoint > 0) 
	do
		if wavePoint >= 5 then 
			local numMonster = math.random(1, 5)
			wavePoint = wavePoint - numMonster
			monster_name = monster_list[numMonster]
			factory.create(monster[monster_name].factory_url, position, nil, {damage = monster[monster_name].damage, speed = monster[monster_name].speed, hp = monster[monster_name].hp, height = monster[monster_name].height, experience = monster[monster_name].experience})
		else
			local numMonster = math.random(1, wavePoint)
			wavePoint = wavePoint - numMonster
			factory.create(monster[monster_name].factory_url, position, nil, {damage = monster[monster_name].damage, speed = monster[monster_name].speed, hp = monster[monster_name].hp, height = monster[monster_name].height, experience = monster[monster_name].experience})
		end
	end
end

1 Like

There’s also some repeated code within the if and the else that you can clean up.

The only difference between the if and else is the math.random(1, 5) compared to math.random(1, wavePoint). So you can replace that line with:

local numMonster = math.random(1, math.min(wavePoint, 5))

…and then you don’t need the if and else statement at all and you can remove the duplication.

2 Likes