transition performance question

In my game I create a lot of enemy waves and move them with transition.to along a path.

The enemy numbers can get really huge… something like 100 waves * 20 enemies. Each enemy then moves on the path from point to point where it changes it’s direction (which is a new transition to a new position).

I completely cancel the transitions when they reach a goal or an enemy is destroyed. I also remove all enemy graphics.

BUT: I still have performance issues when the wave count goes above 60! I have no idea why this is happening.

Do you have some suggestions, idea for what can cause this? A memory check shows the graphics are destroyed correctly it seems during gameplay.

Is there anything else to look into?

Thanks for your help!

UPDATE: I now have checked the used system memory a little bit closer and in the later waves and it seems it is getting too big. It starts with 20 MB and counts up, then falls back to nearly 20 MB … but it later grows and counts up to over 60 MB when the lags are starting a lot and then only falls back to 32 MB to start growing beyond 64 MB.

How can I keep the system memory usage low and what can cause this to grow so much?

Are you using sprites rather than individually loaded images?

yes!

There are several potential culprits. For instance, you may have one or more memory leaks. It may also be the case that you are performing too many calculations and whatnot at the same time. Without seeing your code, these are purely guesses.

How often do you calculate the new routes for the enemies and do they all use the same route or do you calculate 2000 unique paths, etc.?

As for possible memory leaks, write a loop where you create something like 100 enemies, then delete them and wait a bit. The memory used will rise when you first create new variables, but it does go down to a certain level once you delete those variables. If your memory usage grows between these subsequent loops, then you have a leak.
 

If I remember correctly transitions also generate memory leaks if you don’t store a reference to them, and then nil them when they complete.

thanks for your fast help!

Regarding the transition references: Does this mean when using just

transition.to (...) transition.cancel()

this will NOT get removed from memory?

Only if I do something like

mytrans= transition.to (...) transition.cancel() mytrans=nil

I seem to remember that being my experience - similarly with timers. Easy enough to test, create 1,000 transitions in a loop and see what happens to the memory.

I have found one other thing: I have an enemy array which is storing all new created enemies like this

Enemy={} Enemy[#Enemy+1]=thenewenemy

Later when an enemy is getting destroyed I remove it

display.remove(thenewenemy) thenewenemy=nil

BUT the Enemy array still exists which means the enemy will not get removed from memory, right?

I am using Enemy for checking collisions and now have to find a way to still check collisions on all (still existing) enemies and keeping an overview on enemy indexes and the count without an array like Enemy getting too big with growing waves.

Mhh?

One more thing: Could an enemy collision check inside a for loop causing the performance issues when the enemy count reaches about 1000 enemies? (with a simple circle collision detection code)

That’s exactly the point I tried to, poorly, make before :smiley:

If you were to create 1000 entries to your Enemy table, i.e. Enemy[1] through Enemy[1000], those entries will still exist in memory even if you remove the associated display object and set them to nil. However, the only thing about them that exists is the reference and the “nil” value. However, this is as high as the used memory should rise. If you create those 1000 enemies and then delete them, you are left with X amount of memory used. If you repeat the same process, i.e. create and delete those 1000 enemies, then the amount of memory used should not increase after each loop.

Now, if you create a loop that runs 10 times, first creating 1000 enemies, then deleting them all and waiting a while before doing it again, then you should see that the memory after each loop should be more or less the same. If you find that the memory used is climbing after each loop, then you have a memory leak.

Oh, and as for the collision detection, you may also run into issues there. Read through https://docs.coronalabs.com/guide/physics/collisionDetection/index.html.

It really depends on what type of collisions you are interested in. If you are just looking at if an enemy collides with the player character, then you’ll want to go with the local collision handling. Physics can get quite heavy if used too liberally. For instance, using dynamic bodies when static bodies would do is sure to lead to higher than necessary resource usage.

Thanks again!

I am just testing something else:

I have a listener attached to all enemies like this

enemy.touch=theEnemyListener enemy:addEventListener("touch",enemy)

And later when the enemy is getting removed (but NOT in the Enemy table!!!) I do:

enemy:removeEventListener("touch",enemy)

BUT I still have stored the enemy.touch=theEnemyListener then, because the Enemy table ref is still there, right. So with 1000 and more enemies this also can get huge I guess.

So with doing:

enemy.touch=nil

there should be an increase in performance I hope.

it isn’t bringing a lot of speed :frowning:

One more thing:

is there a way to store the new created enemies in an array and “safely” remove them from this array fast! So this array can be used to do a collision check with a circle circle collision detection (not physics)?

Right now I just store every enemy in the array (means a reference) which get’s too much with a LOT of enemies. I should remove the destroyed enemies from this ref table also, but how can I do this in a fast way and still use the table to do the collision check?

UPDATE: I will remove this question to another thread because it is off topic here.

Are you using sprites rather than individually loaded images?

yes!

There are several potential culprits. For instance, you may have one or more memory leaks. It may also be the case that you are performing too many calculations and whatnot at the same time. Without seeing your code, these are purely guesses.

How often do you calculate the new routes for the enemies and do they all use the same route or do you calculate 2000 unique paths, etc.?

As for possible memory leaks, write a loop where you create something like 100 enemies, then delete them and wait a bit. The memory used will rise when you first create new variables, but it does go down to a certain level once you delete those variables. If your memory usage grows between these subsequent loops, then you have a leak.
 

If I remember correctly transitions also generate memory leaks if you don’t store a reference to them, and then nil them when they complete.

thanks for your fast help!

Regarding the transition references: Does this mean when using just

transition.to (...) transition.cancel()

this will NOT get removed from memory?

Only if I do something like

mytrans= transition.to (...) transition.cancel() mytrans=nil

I seem to remember that being my experience - similarly with timers. Easy enough to test, create 1,000 transitions in a loop and see what happens to the memory.

I have found one other thing: I have an enemy array which is storing all new created enemies like this

Enemy={} Enemy[#Enemy+1]=thenewenemy

Later when an enemy is getting destroyed I remove it

display.remove(thenewenemy) thenewenemy=nil

BUT the Enemy array still exists which means the enemy will not get removed from memory, right?

I am using Enemy for checking collisions and now have to find a way to still check collisions on all (still existing) enemies and keeping an overview on enemy indexes and the count without an array like Enemy getting too big with growing waves.

Mhh?

One more thing: Could an enemy collision check inside a for loop causing the performance issues when the enemy count reaches about 1000 enemies? (with a simple circle collision detection code)

That’s exactly the point I tried to, poorly, make before :smiley:

If you were to create 1000 entries to your Enemy table, i.e. Enemy[1] through Enemy[1000], those entries will still exist in memory even if you remove the associated display object and set them to nil. However, the only thing about them that exists is the reference and the “nil” value. However, this is as high as the used memory should rise. If you create those 1000 enemies and then delete them, you are left with X amount of memory used. If you repeat the same process, i.e. create and delete those 1000 enemies, then the amount of memory used should not increase after each loop.

Now, if you create a loop that runs 10 times, first creating 1000 enemies, then deleting them all and waiting a while before doing it again, then you should see that the memory after each loop should be more or less the same. If you find that the memory used is climbing after each loop, then you have a memory leak.