How to implement monster spawning with delay?

Hello, as a result of writing the game I ran into a misunderstanding of spawning mobs with a certain cooldown. When using the code inside the function, its execution is instantaneous, at the same time I tried to use timer.delay, but nothing worked + when using it, monsters spawned and immediately disappeared.


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

Here’s how I tried to implement .delay

{...}
		if wavePoint >= 5 then 
			local numMonster = math.random(1, 5)
			wavePoint = wavePoint - numMonster
			monster_name = monster_list[numMonster]
			timer.delay(1, false, function()
				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)
{...}
1 Like

Is your ‘position’ variable defined somewhere? Looks like it’s passed to factory.create but not defined beforehand. That might be why your monsters disappear.

No, unfortunately, factory.create() itself works completely correctly + immediately after monsters appear final() is triggered (as part of the test after removing mobs in the console writes how much experience they brought).

Weird, turns out some monster disappears after appearing, I’ll go double-check the script of the monsters themselves.

As it turns out I forgot to prescribe collision groups to all monsters except ogres. As a result, when spawning they hit each other and instantly disappeared, this problem has been solved.

But there’s still a problem with their appearance, because timer.delay() will still spawn them all together, except that it won’t be instantaneous, but after 5 seconds. (I need them to spawn one by one with a delay).

image

Actual script:

function mobSpawn(self, wavePoint)
	while(wavePoint > 0) 
	do
		if wavePoint >= 5 then 
			local numMonster = math.random(1, 5)
			wavePoint = wavePoint - numMonster
			local monster_name = monster_list[numMonster]
			timer.delay(5, false, function()
				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)
				else
			local numMonster = math.random(1, wavePoint)
			wavePoint = wavePoint - numMonster
			local monster_name = monster_list[numMonster]
			timer.delay(5, false, function()
			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
end

Instead of using a while loop, which will run infinitely on the first frame until everything is spawned, you should delay the mobSpawn function itself to make them appear one by one. For example:

function mobSpawn(self, wavePoint)
	if wavePoint > 0 then
		if wavePoint >= 5 then 
			local numMonster = math.random(1, 5)
			wavePoint = wavePoint - numMonster
			local 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
			local 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})
		end
		timer.delay(5, false, function ()
			mobSpawn(self, wavePoint)
		end)
	end
end
4 Likes

Is it a recursive function ? This is the first time I see its use in practice, thank you very much !

Can I explain its work in a separate post ? I’ll mention you, of course.

Sure, if the code works for you, feel free to share the approach.