Using factory.create inside a for loop, can't send message to right instances (SOLVED)

Hello!

I’m really liking Defold so far, but I’ve run into an issue I can’t solve. I want to create a varying number of enemies using a for loop and a factory.create call at different points in my game. I can indeed create the number that I want with the loop, but for some reason I’m not able to send messages to the right newly created object. Here’s my code:

local enemies = {}

function spawn_enemies(self,num_enemies)
	local enemy = {}
	for i=1, num_enemies do
		enemy[i] = factory.create("enemyContainer#enemy_factory", vmath.vector3(0,0,0.1))
		print("just spawned ",enemy[i])
	        msg.post(enemy[i], "spawn_enemy", {enemyNumber = i, myGrid = grid})
	        table.insert(enemies,enemy[i])
	end
end

Inside the new enemy’s attached script, here’s the on_message block for spawn_enemy:

local name

function on_message(self, message_id, message, sender)
    if message_id == hash("spawn_enemy") then
    	print("spawning "..message.enemyNumber.." in the script of",name)
        name = "enemy"..message.enemyNumber
    end
end

Here’s the printouts, in order, that this code produces:

DEBUG:SCRIPT: just spawned 	hash: [/instance0]
DEBUG:SCRIPT: spawning 1 in the script of	nil
DEBUG:SCRIPT: just spawned 	hash: [/instance1]
DEBUG:SCRIPT: spawning 2 in the script of	enemy1
DEBUG:SCRIPT: just spawned 	hash: [/instance2]
DEBUG:SCRIPT: spawning 3 in the script of	enemy2

So, as you can see, it spawns 3 instances all with their own unique path, but for some reason the msg.post to the new instance somehow gets sent to the existing instances. What’s even weirder is that, if I print out the name of all 3 of these instances from their scripts after spawning all 3, they’re ALL named “enemy3”, meaning they all get overwritten with the next call.

I’m sure I’m just doing something wrong here (I don’t typically work in Lua and I’m new to Defold), so please let me know if there’s an easy fix to create multiple objects in a for loop like this!

Thanks!

EDIT: It’s worth noting that I tried moving the for loop out of spawn_enemies and just calling that function separate times for each time I wanted to create a new enemy, but it produced the same result.

You are setting the name property after the print call, resulting in the last enemies name being printed. A local variable is shared among all instances of that script, so instead of a local variable use self.name and move the “name = …” to before the print.

Ahh, that did it! The print statement is in the right place (it SHOULD print “spawning [num] in the script of nil” if it were doing this correctly), but I didn’t realize local variables are shared across all instances. That seems counterintuitive. The “self.name” thing completely fixed it. Thank you very much! Just a noob mistake :slight_smile: figured it was an easy fix.