Overflow! Each collection allocates memory by numbers from the game.project (SOVLED)

We are faced with the lack of memory.
We have one main collection, which contains most of the game objects.
We setup large limits for the number of objects:

At this stage, everything works predictably.
After that we generated more than 60 small collections for use through the proxy load/unload.
And here we got a problem. Each collection allocates as much memory for itself as specified in the game.project! Under 5000 objects in our case for each small collection!

We need to explicitly specify in the collection properties how much memory needs to be reserved for the objects of this collection. For example, in our small 60 collections it is a maximum of 20 … 30 objects per collection.

1 Like

You have 60 collection proxies that you load/unload? Why? Are they all unique or could you perhaps instead spawn them using collection factories? Remember that we will not batch draw calls across loaded collections.

@britzl I think this is the reason (As I know guys are working on BIG game with many assets)

Does Defold has other way to load and unload textures into the memory?

All 60 collections are unique.
In fact, there will be more than 100 of them and each has a unique textures and animations:

Unfortunately, with all the desire they can not be put into same draw-calls, because the textures and animations for each collection already go beyond 2K * 2K.

Simultaneously, a small number of such collections are displayed on the map, presumably up to 20, so we do not have a problem with the draw-calls bottleneck.

The main problem that currently freeze the development is memory overuse by collections. :frowning:

2 Likes

Are you saying that you want to have 20 objects on screen at the same time, each pulling graphics from a 2048x2048 texture?

That’s about 670Mb of texture data.

And if all of the 20 objects aren’t unique, then how many unique objects will you have?

What does each collection consist of? I’m assuming it consists of a collectionfactory and the collection that represents the actual object/building to create.

How does this manifest itself btw?

Nearly. But not so dramatic. The atlases contains “various building configurations”. Some atlases are less than 2K. Now this is not a critical problem for us.

Ok, so what is the actual problem? You mention memory issues? How does these memory issues manifest themselves?

Are the numbers in the original screenshot correct? 256 collection proxies, 5000 factories, 5000 instances per collection? Will you actually have 256 collection proxies? 5000 factories sounds very high.

What does “Instances” value mean?

The actual problem is that each collection allocates full memory specified in the game.project.

I created a project with hundreds of collections that are created through a proxy.
These are empty collections.
I took the project settings the same as the working project.
Result:

In other words, 27 empty collections required 133 MB of memory! This is the problem.

We need to control the amount of memory allocated to the entities within the collection.
For a large collection, we really need more than 4000, but for small ones 20 would suffice.

I think guys want something like a gui and nodes, when developer can set maximum of node counts for each gui component.
Would be great to have the same thing for collections proxy and property in game.project can be used only for main collection.

2 Likes

YES!!! Y E S !!!11

In our real project, the numbers are:
Roads = 11,
Tiles = 375,
Resources = 410,
Rocks = 144,
Clouds = 203,
Decals = 247,
and over 2000 instances for all characters animations.
All this within the same collection.
That’s why we had to specify 5000 instances in game.project

About animations - it was very unexpected to learn that one Spine character has up to 100 GO-instances!

Yes, Spine animations require one GO per bone. Game objects are very cheap though. They are the smallest building block in the engine.

Note though that transforming thousands of bones/game objects each frame might cause problems on mobile. I’ve tried animating 200 or so characters with 30 bones each on an iPhone 6. It ran in 60 FPS fine but the engine was pretty busy.

Regarding memory consumption. @sven or @Mathias_Westerdahl can probably clarify a bit, or @Ragnar_Svensson. I think that the intended use cases for collection proxies are different from what you are trying but I leave it to the engine experts to answer that.

An empty game object instance in Defold is equivalent to a scene graph node in another engine, e.g. a specific skeleton bone, or something as small. They are not equivalent to an instance in e.g. Unity. In Defold, it’s an entry in a few arrays as opposed to a dynamically allocated heavy-duty object. In terms of cost, they are much closer to particles in a particle system, than an NPC for example.

The typical use case for a collection proxy is to do dynamic level loading, or possibly to run two game sessions simultaneously (to do cross fades or similar). It’s not meant to solve asset streaming. Since there is no support for asset streaming currently*, we understand that many use collection proxies as a workaround for this. So rather than changing how collection proxies work in this aspect, we would need to implement streaming support to solve the problems you are facing in a good way.

*) I believe it’s possible for users to achieve asset streaming to some degree using native extensions and the buffer api, but it would probably be a pretty challenging exercise.

4 Likes

I know several possible solving of problem, and all of them has bottleneck on engile side.

  1. Replace RGBA textures with RGB, and one more RGB texture can use R, G and B channel as alpha for three different texture. Small shader, and it can work, but:
    - defold can’t use two textures in material

  2. Polygonal sprites (can use with point 1, and help to make better compressin sprites with alpha) - I told about it here.

  3. And, of cource, assets streaming.

All this features “must have” for any 2d engine because every 2d game use too many sprites with alpha chanel, and every big game will be have a memory problem.

1 Like

The problem I described is very serious for us.
In fact, we can’t continue developing further, because the game does not start on low/mid smartphones due to memory overruns.

The ideal solution would be the ability to individually setup for each collection the number of instances for it. The collection is a very convenient form of storing game asses. I think it would be very convenient to implement the assets streaming.

Where can I read more about this (buffer api)?

There are several possible ways forward, but it is unlikely that collection proxies will be rethought to cater for your use case. Proxies are used to create whole game world instances so there is a lot of systems that come with them, for instance separate physics worlds. The instance counters have little effect on memory consumption so individual counters would not solve the problem.

Proper asset streaming is a future feature that will require lots of design and a thorough implementation process. It will likely happen at some point in the future but there are no concrete plans.

For your case: there are ways to lessen the memory footprint of textures. Have you looked at hardware texture compression, removing alpha and such? Also, support for 16 bit textures is in the works.

Another option: does your design permit separating the game into larger “chunks” that can be loaded via proxy the way they are intended to be used?

1 Like

Sidenote: I’ve added a clarification warning to the collection proxy manual.