Yes ![]()
Then that shouldn’t be a bottleneck in terms on spawning them. It would maybe count for thousands or maybe even hundreds of thousands of enemies, I think, you would need to measure it. What would matter most probably is the frame time with all of them on screen - so what materials are used, what rendering pipeline, if those are 3D models then also how many polygons, etc. It all really depends. But when it comes to spawning it should be neglectible.
This is a too generic statement to be answered if it’s true or not, so a generic answer to such generic question would be “no, it’s not true”.
Maybe if what’s @Mathias wrote:
would really affect the creation and that might be true (also depends on what you’re spawning mainly and in what amounts) and as @britzl said above it would be most probably hardly noticeable.
A single collectionfactory.create() usually does more work than a single factory.create() if the collection contains multiple game objects, because it creates multiple instances and reconstructs their hierarchy. The alternative - manually calling factory.create() several times from Lua and then parenting everything yourself shouldn’t really be vastly different, but the only honest answer is to measure in the target case.
Collections differ from game objects in Defold, because collections are only files, there is no “collection” in runtime - collection is only a file/data telling game engine to spawn X game objects with this hierarchy, when this collection is loaded. Therefore there is a difference when loading collection and spawning collection. Spawning - via collectionfactory - is just spawning X game objects with a given hierarchy into currently existing game worlds where the factory is.
Loading through a collection proxy creates or loads a separate runtime collection - a new world with new physics world and a new namespace for addressing. Loading resources for a collection factory is something else: it only prepares the prototype resources used later by collectionfactory.create(). And loading can be done asynchronously. This is therefore used for loading levels, menus or very heavy collections, etc.
Why there are collections then in Defold, when in other game engines, like e.g. Unity you can just nest in prefabs?
TL:DR; It’s all because of the architecture of the game engine. In Runtime only Prototype instances exists and they contain Components, but does not contain other instances - instead a graph of hierarchy is a separate entity that is tracking parent-child relationships and helps e.g. in transforms calculations.
So the .go is a file - a prototype. It can be “included” in another file - called .collection, so that’s why we can add game objects on the left side of the Editor, in the Assets pane as files and add them to collections on the right side of the Editor, in the collection’s Outline - embed them inside a collection file.
The Game Object instance is a runtime equivalent to what is stated in the .go file or embedded inside a .collection file that is instantiated inside the game’s world.
A .collection file is not instantiated at runtime as a first-class “collection object” that you can manipulate like a GameObject. When spawned through collectionfactory, it is used as a data template describing which game object instances to create and how to parent them. However, Defold does have an internal runtime Collection structure representing a game world / collection context, especially for bootstrap collections and collection proxies.
Could then the .go file reference other .go files as .collection does?
Yes, it’s conceptually possible, Defold could move toward allowing game objects to nest other game objects in a way that would reduce the distinction between .go and .collection. The team has discussed merging these concepts, but this would be a breaking change, requiring a refactor of the engine code, of the ideas that are there since the very beginning, and therefore not something you should rely on today. Having a collection as a special idea is very well aligned with the data-driven approach in the engine architecture and it corresponds to how the relations in runtime are structured .
The Components in Defold are contained inside a Prototype instance (Prototype “has-a” Component):
Runtime Instances point to a Prototype, and component instance data is allocated separately through Component Worlds.
But Defold does not contain other Instances inside, instead it only has other instances indexes, e.g. a parent and children. Defold is focused on making structures as flat as possible. Defold doesn’t have a complex object oriented structure for a tree of the scene or the world, instead has arrays and instances only have indices to those arrays.
This flat, index-based representation is one of the architectural choices that helps Defold keep runtime data compact and predictable.
So the architecture is vastly different and that is what drives Defold performance.
@JCash or @britzl can perhaps correct me, if there’s something wrong here, that’s only my current understanding of the engine ![]()