Deactivating objects vs. Create/Destroy

  • I've been working on a bullet hell shooter for awhile now. The performance is pretty good, but I'm trying to make some further optimizations.

    One thing I'm wondering is if anyone else has compared activating/deactivating objects -- ie., moving them offscreen and disabling collisions, etc. -- vs creating/destroying objects. I'm specifically interested in cases involving high numbers of small, short-lived, similar objects, such as bullets and explosions.

    Right now I simply spawn bullets as needed, and destroy them when they go offscreen. I was under the impression that this was a workable approach since C2 did some form of object pooling, but I can't find any reference to that now. The highest onscreen object count I'm dealing with is between 1000-2000.

  • I would like to know this, too... I have random thoughts on it which are based on nothing whatsoever, so I will keep them to myself.. heh.

  • I'm actually very glad that you brought this up - gave my a nudge to test this myself!

    I remember Ashley making mention of something like this sometime ago with regards to someone's question about performance with individual rain drops as sprites. He suggested then that it'd be more efficient to move the rain drops to the top of the screen when they hit the ground, instead of destroying and recreating them.

    I made a quick test to see this sort of problem in action, and, provided my testing methodology is accurate (I think it is), it's definitely more efficient to move objects than to destroy and recreate them. With this test, on my machine, I started to see frame-rate wobbles (or "pulses", as it appears in this test) around the mark of 3,500 instances with the destroy/create method, whereas with the move method, I could take the instance count up to 15,000 before the frame-rate dropped below 60 fps (once it got up to speed, that is). And even then the frame rate, when lower than 60, would be very stable up to about 35,000 instances.

    Try out this demo yourself. You might need to adjust the repeat or sprite count checks, depending on your machine's hardware, to find the point at which the difference between the two techniques is the most noticeable.

  • I'm actually very glad that you brought this up - gave my a nudge to test this myself!

    I remember Ashley making mention of something like this sometime ago with regards to someone's question about performance with individual rain drops as sprites. He suggested then that it'd be more efficient to move the rain drops to the top of the screen when they hit the ground, instead of destroying and recreating them.

    Hah, that's funny...that's where I got the idea too!

    I did a test yesterday and found much the same thing: with large numbers of objects, there is a noticeable gain with 'de-activation' vs create/destroy.

    I'll check your capx out later today.

  • That's pretty interesting!

    I'd be very curious on how this method can be applied on a full game with tons of particules, trails, and projectiles, with different settings on each.

    It sounds like our games could get a perf boost, but at the same time, It sounds like a *hell* of a work to make everything this way too...

    I get how to apply this on simple things like rain, but how would you apply this to a firework explosion where each bullet has its own angle for example?

  • Well, I hacked it into my game last night. Didn't take but an hour or so, but:

    a. My game is way less complicated than Penelope, and...

    b. To maximize the benefit, I'll need to restructure some of my logic. That will take more work.

    In my case, I added a boolean called Active to my player bullets family. Then I went to where bullets were normally destroyed (when colliding with enemies, and when going offscreen) and, instead, simply moved them offscreen, disabled collisions, and set Active to false.

    I then went to where I was creating them, and simply looped thru (Active != true) instances by iid(loopindex), repositioning them, re-enabling collisions, and setting them to (Active = true).

    After that, I went to where I was moving my bullets, and added the (Active = true) condition. This way, inactive bullets won't be flying around in the offscreen netherland.

    Finally, I added logic that slowly spawns in (Active = false, collisions = off) bullets offscreen when entering the game layout, stopping at about 1600 instances (the highest number of player bullets that can be onscreen at any one time). This gives me a sufficient cache for the rest of the game.

    The result of all this was a marked improvement in performance, as tested in chrome(preview), firefox(preview), node-webkit(preview), and node-webkit(export). Overall CPU usage was reduced by 20 t0 25% in chrome/node, and performance skyrocketed in firefox by almost 110%. The caveat there is that firefox performance was poor in both cases...I haven't updated it to a current version in awhile. I'll test it again tonite with firefox 33.

  • Wow, that's a MASSIVE difference in performance between the two! For extra fun, leave both tests enabled simultaneously and watch the trippy fun!

    Now as far as big games go, in the case of Penelope, I suppose during the start of your levels, you could spawn in all of the necessary objects before your fade-in (so users don't see the chug) and then just run loops in functions each time you need an explosion and have it pull from your cache of off-screen objects. It would be a pain and would be tough to retrofit in a game that is probably as far along as yours, but given enough instances of this, you might actually boost framerates on lower-end PCs by a worthwhile margin. It would just be time-consuming.

    But maybe that's why I've been able to get so many objects on-screen at any given time in Courier. They're largely static (well, they move, but most aren't created dynamically). All of my levels are pieced together from lots of smaller pieces (to reduce how much of a hit your GPU will take and so I don't have to draw as much), but they aren't being actively created and destroyed on the fly. The only things that do that are effects, and I suppose I could probably improve things a little this way. I could probably manage more particles, fireflies, dirt in the air, etc. this way. I'll have to give it a try. I always knew it was more efficient, but that's a dramatic difference!

  • Construct already does this to some extent for sprites by recycling them, so i'm curious why the discrepancy in performance is so big, ideally it shouldn't be.

  • Yeah, C2 definitely is supposed to do a lot of recycling like this under the hood, I'm surprised the performance difference is so big.

  • Running GeometriX 's test I get more than twice the particles with 60 fps with the repositioning method. So I guess there is actual benefit to try and recycle the same Sprites.

    It's very useful to know, thank you all!

  • Wow, thanks GeometriX for the example test, there's a huge difference in performance (4k v 15k)! Now I'm going to make some adjustments to the jitter examples that eli0s and I created for the jitter thread - and see what happens there with respect to garbage collection....

    Edit - I've posted an example of the jerkiness thread - definitely advice worthy of note!!

  • Colludium , thanks for the new test! I am experiencing some mixed results, I wrote about it on the other topic.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I also do this on my isometric engine for the walls. First set amount is created and after that just moved.

  • All these threads about jerkiness and destroy/desactivate are really helpful.

    Thanks a lot for the explanations, I'll try to change a few things and see how it goes : )

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)