Function called can only access instances within the same collection

Why go api and factory api limit access. but msg.post does not? So, how can I get position from game objects in different collection?

I just started to use collection proxies to structure my game dynamically, instead of just placing the collections directly. And then I had to change many of code base, especially, to add socket to every msg.post code. Before that, I could use "/battle/hero" now I have to use "battle:/hero" instead.

Also before that, my controller_script could call go.get_position("/battle/hero") but now it cannot found the game object. so, I change to go.get_position("battle:/hero") and I get the error message same as the topic.

My game structure (Before using collection proxies):
main.collection

  • battle.collection (a collection)
  • title.collection (a collection)
  • controller (go)
    — contoller_script

My game structure (After using collection proxies):
main.collection

  • loader (go)
    — battle (a collection proxy)
    — title (a collection proxy)
    — loader_script
  • contoller (go)
    — controller_script

Now I think the cost of switching structure from placing collection directly to be using collection proxies is very expensive becuase I have to refactor large code base…

Maybe I done something the wrong way again…

It’s a bit hard to understand your reason for using collection proxies. They are intended to be used for things like whole levels. One thing to consider is that each collection proxy creates a different physics world. See http://www.defold.com/doc/collection-proxy

Regarding communication between objects. You can easily get the position from any game object with go.get_position(). Just reference it by an url. See http://www.defold.com/doc/message-passing about how to address objects and http://www.defold.com/ref/go#go.get_position

Especially pay attention to absolute and relative paths. In practice you should almost never need to specify socket in your addresses. “/battle/hero” refers to “hero” in the collection “battle” in the current world and as long as the script logic that sends messages to the “hero” object is part of the same world (or collection loaded by proxy) you can restructure at no cost.

1 Like

OK, I just not sure how to do things like “title scene”, “battle scene”, “main menu scene” and thought that collection proxies were the answer. Is it better to just embeded them all (title.collection, battle.collection and mainmenu.collection) directly in main.collection and just enabled/disabled them. Do you have a way to enabled/disabled the embeded collection (not using proxies)?

About communication between objects. As you can see from my game structure at the 1st post my controller_script belong to main.collection and is part of neither “title” nor “battle” collections. My question is when I embeded collections I can call go.get_position("/battle/hero") from that controller_script and successful get the position but when switch to collection proxies how can I get the position of my “hero” object in “battle” collection that was loaded by the proxy? neither go.get_position("/battle/hero") nor go.get_position("battle:/hero") work.

Thanks.

Collections are not a runtime concept so there is no way to disable and enable everything inside a collection.

Yes, I understood that the controller script was part of main. What is the purpose of that script? I.e. what kind of messages do it send to “hero”?

(Note: You’re right that you can’t probe game objects, like do a go.get_position(), over world boundaries)

1 Like

I just go back to use embeded collection with GUI as mainmenu and title. Also just break the controller_script to be in title.collection and battle.collection now everything seem good.

Thank you :smile:

Well, the question is why you don’t have the controller script in the battle collection? If the script controls the position of “hero” it might even belong inside the “hero” game object.

1 Like

I agree with @sicher when it comes to the controller script. It sounds like it should be placed “closer” to the hero.

BTW, my experience with collections is to use them to structure the different parts of the application like this (don’t take this as the way to do things, it’s just my view on things and my experience of what has worked well):

loader.collection
This is the bootstrap collection that i set in game.project. It’s purpose is to show a splash screen and then load a main collection.

main.collection
The main collection will when enabled do some initial setup of app state. It has collection proxies to a menu collection, shared collection and a game collection. When setup is done it will load the shared and menu collection. Once all this is done it will post back to the loader to hide it.

menu.collection
The menu collection contains things such as a start screen, settings screens, pre game/level select and so on. When the game starts the game collection is loaded and the menu collection is unloaded. You could split up the different screens in their own collections, but I don’t really see much point to this unless you have a lot of screens that drain too many resources.

shared.collection
The shared collection contains things that should be available both from the menus and in the game. It could be basic popups, maybe a topbar with player avatar and so on.

game.collection
This collection contains all of the game logic and game screens. It can be further divided into several level collections, but should probably not be divided into smaller parts than that. Once the level is completed or the players opts to return to a main menu the game collection is unloaded and the menu collection is loaded again.

4 Likes

Thanks for sharing your experience. It looks good, I will try to structure my game by using collection proxies again in the future :smile:

Thank you very much both of you!