Confusion with factory object naming

I am creating my own touch controller and I am having trouble to get correct name from factory objects that touch is colliding with.

when my touch collides with obj from factory I set

function on_message(self, message_id, message, sender)

	if message_id == hash("collision_response") then
		print(message.other_id)
	end

and factory object is created with

objectName0 = factory.create("/some path")

And when I debug my mess, as a message.other_id I am getting instance0 instead of objectName0

I am confused, why do I get as a name instance0 instead of objectName0?

Internally in the engine, ids must be unique.
So when you instance an object more than once from a factory, we need to come up with a new name. I.e. instance0, instance1 and so on.

Also note that objectName0 is a variable in your script. It stores the id of the object you created. The vaiable may have any name, and it totally unrelated to the actual id.

I made a quick test to illustrate. Object b spawns object a and stores the reference as so:

a = factory.create("#a")

They then collide, at which point I compare message.other_id to the stored id:

    if message_id == hash("collision_response") then
		print(message.other_id, a)
		go.delete()
	end

Output:

DEBUG:SCRIPT: hash: [/instance0]	hash: [/instance0]

Project:
factorytest.zip (3.6 KB)

Like Mathias says, I think you are confused about the variable you use when spawning with a factory. factory.create() returns the global id of the newly spawned object, which you are storing in whatever variable you provide. The name of this variable (you call it ‘objectName0’, I called it ‘a’ in my test) has nothing to do with the id that factory.create() has provided.

API reference here: API reference (factory)
Manual here: Factory component manual

1 Like

Oh, I see, thank you both for clarifying that for me .

What confused me the most is, when I ask spawned factory object to identify touch controller object name (that was already in main.collection), it printed correct name “go_touch_controller”.

And I was asking myself, if factory pulls from library prototype named “go_some_name_i_gave” why during spawning in main.collection is not keeping the same name of that prototype I initially gave but it renames it to instance0, even if it’s the only spawned object from that factory.

So my problem now is, how should I receive the initial name of that prototype object that was passed trough factory (go_some_name_i_gave)?

Or, even better question is, should I use factory at all? Because I am using factory only to spawn prototype object once, and that’s it. And I am using factory for one prototype only just to not stress the memory and loading time (cuz later on I am planning to have 20 different prototypes in total that will be spawned only once, at some point in the game). And basically they have to have exact name I gave them for further comparison with other variables from tables for activation purposes, etc.

It really depends on how you structure your project.

In the simplest terms, I would store the ids in a table.

local prototype_id = factory.create(...)
table.insert(prototypes, prototype_id)

If you have some central manager script, I would relay the id via a message:

local prototype_id = factory.create(...)
msg.post(url_to_manager_script, "new_prototype_spawned", {id = prototype_id})

The manager script would then presumably store the id in a table.

You can easily store the id along with other fields in a table.

local prototype_id = factory.create(...)
table.insert(enemies, {health = 10, damage = 5, id = prototype_id)

Just some ideas, I’m sure you can figure out something that works for you.

I think the name “prototype” here is a bit confusing.
We use the word prototype to mean “something that we use as template to copy from”.

In your example, I’d rename it “instance”, since it is an instance of a prototype.

local instance_id = factory.create(...)
table.insert(instances, instance_id)
2 Likes

Good point, you’re right!

hmmm, I see.

I will try to simplify what I did so far, cuz I divide things in too many scripts that is hard for me to paste all here and to make sense.

So,

I have 3 factory objects, named:
factory_circle, factory_rectangle, factory_triangle, with go prototypes associated with them.

Then I have a table with names same as a factory names:


local shapesTable = {'factory_circle', 'factory_rectangle', 'factory_triangle'}
	

after that I am spinning random number, to pick some of available shapes

local shape = math.random(#shapesTable)
require "main.moduleScript"    ---> module script to collect name of the shape and play sound function



--- spawn first shape
shape1 = factory.create("#"..shapesTable[shape], somePosition)
mShape1 = shapesTable[shape]  --->stored in module script for sound function
table.remove(shapesTable, shape) 
Sound1() ---> from module script

--- spawn second shape
--- random math for the rest of the shape in tables and so on 

then I have a module script where I want to store spawned names in a variable cuz they will activate some sound that has again, same name as a factory

--moduleScript

mShape1 = nil
mShape2 = nil
mShape3 = nil

function Sound1()

sound.play("main:/go_soundController#".. tostring(mShape1), nil, nil)

end

--- and so on, another functions for other shapes

and that’s why I need exact names of objects during collision with touch, cuz this is how I orginize things before to recognize each other.

I would extend your shapes table to contain more information than just a factory name. That makes it needlessly restrictive.

local shapesTable = {
    circle = {factory = "#factory_circle", sound = "main:/go_soundController#circle"},
    rectangle = {...},
    triangle = {...},
}

Then, for example, to spawn:

shape1 = factory.create(shapesTable[shape].factory, somePosition)
1 Like