Collection proxy doesnt reset

Hi. Im using the collection proxy for instantiate all the game, when I finish, I unload all, and return to main menu. But if the player clicks in play, collection proxy, creates the collection one more time, or should create, but it saves the variables and state before the unload… how can I reset all the collection??

thanks

I tried with colection factory

create

local game=nil

game=collectionfactory.create(“#collection_factory”)

delete

go.delete(game,true)

the collection dissapear, but when I create one more time, I hace errors

“Node used in the wrong scene”

and the collection doesnt reset…

Where do you store the variables and state? On self in a script within the collection that got unloaded (should work)? Or in script local functions or perhaps even in global variables (will cause problems)?

I use self in scripts inside the collection, in modules, and in local variables of the script.

I tried with collection factory, with the dinamical instantiate, and I think , it works. today at afternoon, I deep more.

But How is the aproach for make this works? If I use modules, this modules doesnt resent? the only variables that reset in the instantiation, are the self variables.

whats the point of using a collection proxy instead of factory collection?

we are talking about using the same collection, N times, and the behaviour of the collection must be, like the first time, all clean.

thanks.

Ok, good. I was worried that you stored state in global variables, which would then of course be kept even though you unloaded/destroyed the collection.

Correct. The module is loaded into the global state of your application. You need to manually reset it somehow.

The difference is that a collection proxy can load and unload a single instance. A factory can spawn multiple instances of a collection. So it depends on what you have in the collection really.

then I cant use a collection proxy if it uses local variables?

with the collection factory, when I create one more time the collection, I print the url of a script inside the collection

[main:/collection0/go#logic]
[main:/collection1/go#logic]
[main:/collection2/go#logic]

and so on. Is this normal?

like I said, first I delete all

collectionfactory.unload(“#collection_factory”)
go.delete(game,true)

why are not all the references deleted?

another thing, this collection has a audio component, and if he is playing the music, when I delete the collection, it continues playing…

No idea. It’s really hard to tell without looking at your code. Regard scripts and state:

  • Anything you put in a Lua module will not be affected by loading/unloading of collection proxies or created/deleted by a factory. You need to manually reset the module or unload it by setting it’s entry in package.loaded to nil
  • As for state in scripts have a look here:
-- my.script

-- this variable will be set on the global table and available from everywhere
-- any changes made to it will not be reset by unloading and loading again
this_is_global = 123

-- this variable is local to any instance of my.script
-- any changes made to it will not be reset by unloading and loading again
local this_is_script_local = 123

function init(self)
	-- this variable is unique to this instance of the script
	self.script_instance_scope = 123

        -- this variable is local and only available in the current scope (the init function)
	local this_is_local = 123
end

why are not all the references deleted?

To be honest I don’t know what exactly the Collection Factory 'load' and 'unload' function do, I’ve never needed them, but I don’t think they’re for destroying your spawned objects. Also note, the docs say:

“Calling this function when the factory is not marked as dynamic loading does nothing.”

In other words, if you didn’t check the “Load Dynamically” property on the Collection Factory, then there is no reason for you to use those functions.


I think there’s still some misunderstanding here about the difference between a Collection Proxy and a Collection Factory.

For loading your whole game, or the current “level”, you should be using a Collection Proxy—each one has its own physics world, can be paused, reloaded, etc. It’s sort of like having another game running inside your game that you can load and unload at will.

A Collection Factory is just like a regular Factory—it’s for spawning objects (bullets, enemies, players, etc.), only it can spawn a Collection of multiple game objects instead of only a single game object at once.


If you unload a Collection Proxy, everything inside it will be destroyed. If something was not destroyed, that means it wasn’t inside the proxy collection. Maybe it was data that was stored in a Lua module, or an object or script that was actually in the main collection, not the proxy collection. You can use:

print(msg.url())

To check where your objects are (the text before the “:”). For example: “[main:/root#game_manager]” is in my “main” collection, “[level 1:/player/root#player]” is inside my “level 1” collection, which is loaded with a Collection Proxy (therefore my player will be deleted when I unload the Proxy).

Note that unloading doesn’t happen instantly. I believe it will take 1 frame, minimum. This is why you get a “proxy_unloaded” message, so you can tell when it’s done.

2 Likes

i check the load dynamically, its the only way the collection spawn with reset values.

I tried with collection proxy too, but weirds thing happen when I reload the collection (node disapearing, wrong node errors, and scripts with variables not reset)

In factory collection, like manual says, you use delete recursive in the gameobject the factory create, should delete nodes and references, but like I said, nodea dissapear, but some objects stay in the game, like the go with sound component(music continues playing) and when you create another collection, it gets a new name,(collection1,collection2) then , this is not deleting the nodes, gameobjects or references.

Can you please isolate this down to a minimal example and share it here?

Sure, I see if I have time at afternoon. Its only spawn a collection with a audio component, and destroy it and re spawn it.

done

(cant upload…)

I think Britzl meant to share the project files, so we can help debug the issue, not a build/executable of the project.

1 Like

true. I thought I upload the project, sorry.

Weird, apparently sounds don’t stop playing if you delete the object with the sound component? It seems like a bug to me. I don’t see anything in the docs about this. Though, I also don’t see anything about particleFX continuing after they are deleted, so maybe it’s intentional. That definitely should be clear in the docs though.

@Vik If you want it to work the way you expect, just stop all your sounds manually when you delete the collection. Like so:

function final(self)
	msg.post("#sound", "stop_sound")
end

yeah, but seems weird. furthermore if you use print(url) inside the collection just spawned, the collection of the url always will be different in each instantiation, instead of using the same reference, if you delete the collection, and the go.delete, should do that.

DEBUG:SCRIPT: url: [main:/collection0/lg#logic]
DEBUG:SCRIPT: url: [main:/collection1/lg#logic]
DEBUG:SCRIPT: url: [main:/collection2/lg#logic] //starting game, and exiting game 3 times

it seem to me, that this is a bug, or the delete node is not working as expected.

If i have local collection =factory.create(object) – pseudocode
and spawn in main:/collection0 , when I delete the node, and spawn another one, this collection url must be the same, not collection1, or collection 2

Defold its creating in theory only 1 gameobject, but, the engine are allocating new memory instead using the old one??

and then we have the proof that the music is still playing…

@britzl @sven

Well, that’s pretty normal. Any thing you spawn at runtime will have a generated ID. I’m not sure why it doesn’t go back to zero again if you delete the first one several frames before, but it really doesn’t matter. You should never try to use those names as strings anyway. It will start recycling the numbers at some point. They are just names, I wouldn’t assume that they are directly linked to memory management.

The team can explain it for sure, but as far as I know, objects are pooled behind the scenes and memory is allocated up front based on your game.project settings. The point of Defold is that you don’t have to worry about that low-level stuff, it just works. Don’t start worrying until you actually see performance issues. :slight_smile:

1 Like

Ids of game objects spawned from a factory or collection factory will get a generated id. Sometimes ids are reused and sometimes not, but as Ross says you should not have to care about this.

Defold will allocate most memory up front and not delete and allocate memory at run-time. This is why you have max sounds, max instances, max foo in game.project.

I believe this is intentional. Let’s say you have an enemy game object of some kind and it has a death.particlefx and a death.sound(*) component attached that both are triggered when the game object dies. You want to be able to spawn the particles and play the sound while at the same time deleting the game object. If you don’t want the sound to play you have the final() lifecycle function that you can use to stop the sound if it is playing.

(*) = You probably don’t really want any sound components on individual game objects like in my example though. I think it makes more sense to have all sounds on a separate game object with a scrip that can act as a sound controller to adjust volume, toggle on/off sound and music etc.

1 Like