Some Performance Questions

So yeah, trying to make some performance improvements, maybe someone with indepth knowledge can answer this. I could try this out ingame but it would take a lot of time.

Lets assume I’m running a game with one player_entity and hundreds of shot_hos objects. What would be the best course to optimize this?

  1. Does it matter what is checked first on collisions? Is checking the one entity against 100 more economic?

  2. Does it matter if I do the “do for every shot” part after collision is checked?

  3. Is checking distance more economic than checking collisions? Would the distance check make a difference or would it be more costly?

I dont like using “distance between two object” to simulate colision, i’ve never understood from what pos(x;y) the comparaison is made… I guess it’s object.X() and object.Y(), so if the object is big, or if it could haves a complex collision mask, it’s not that good… And at last i think collision is better than distance checking, because distance checking in a “for each” loop will make distance comparaison to always run… It’s suppositions, and without advanced knowlegde of source code, it’s hard to know… Only 4ian could answer this i guess.

I noticed little performance gain by making less complex collision mask for basic collision condition.

From my own experience, i would only use this (according your actions are on specific “shot_hos” object after collision) :
For each object shot_hos, repeat :

  • shot_hos is in collision with player_entity

All my collisions with interactive objects (ennemies, or physical objects) are based on this, and i use this as routine from performance tests i’ve made with gdevelop v3, 3 years ago (native platform ofc).

Maybe try all the different scenario, with a lot “shot_hos” objects ,and check the performance monitor, and charge of events for each scenario.
I have a performance test in my game where i spawn 500+ objects (and each have several other objects attached (light objects, particles objects), all with AI active. Anytime when i code a new type of interaction (for example a burning effect, with individual duration timer and multiple particles effects), i check the performance : 1) in preview, the test is passed if i have 30+ fps 2) in compiled project, if i get stable 60+ fps.

Then, we have already talked about optimization tips, but take a look on render time (in ms, for visual renderer) : sometimes, optimizing assets can have a huge impact on performance, for example with a 500+ objects on the scene, from bad to well optimized sprites, the render can oscillate between 25 and 5 ms.

Edit : ofc, it also depends on hardware, but always test the compiled project on different hardware. Preview mode can really have bad performance on crappy computers, because the IDE can use a lot of memory. Try also to make your test in fullscreenmode. If you have a laptop with dual gpu (nvidia optimus), you can also make you tests with both integrated gpu and dedicated gpu.

Edit2 : i guess you already use it, in a text field => ToString(1/TimeDelta())
With it you’ll be able to check the number of fps directly the compiled project.

I mean having the collision condition as shown will also have it always run. The question is what’s more economic/makes any difference at all. In the example the objects all have triangle colliders and are smaller than 32x32. I’m pretty sure the position used to calculate distance is the the “Origin” point.

Yeah I noticed that too.

Hm ok, optimize in which regards? Again, in the example I only used small object, and all of the sprites are constantly loaded in memory.

Me too ^^, object.X(), object.Y() : Ok with tiny object only.

Hm ok, optimize in which regards? Again, in the example I only used small object, and all of the sprites are constantly loaded in memory.
[/quote]
For sprites : having the good framerate, wich means preparing the animation with good key frames. With good keyframes selection, 9fps animation can look like a 24fpsone. So reduce at max the number of sprite, don’t use more than needed.
For images : use PNG when transparency is needed only, if not use jpeg. In both case, try to limit the number of colors ( customs color palette). Use image at 1:1 scale, dont reduce it in the IDE. Transparent PNG almost always have useless pixels masked by transparency : use a PNG optimizer to remove it.

For particles system : optimize the particle image (png), optimize the render : number max of particle, duration, flow. Philosophy could be “less is more”

With these few tips, you render time is really high (wich can be a real problem on low spec PC), you can gain some fps.

Another tip on events (but i think i’ve already shared it with you) : if your level is big, disable events for all objects that are far from the “player object” ; do the same for all animated images objects (sprite) or animated by forces : just “pause” it.

When you do a collision test, GD does a fast bounding circle check before the real collision algorithm (SAT) to discard some objects. This means that if you use the distance check yourself as a collision test it will be faster than the GD collision test (because the SAT algorithm won’t be used at all). And if you use the squared distance you’ll get an even faster collision test (because sqrt() is slow).
To check the squared distance:


Where the variable radius of A is the radius of the bounding circle that you want to use as circle shape for A (from the Center point, if you want to use a different center you’ll have to calculate the distance yourself), the same for B. Take into account that if you use a circle-circle collision test, very wide or very hight things like lasers will have a very bad response :imp:

The sources says that the distance condition uses the center point, but I haven’t tried it.

EDIT: I confirm that the centre point is used for sprites, and (X + Width/2, Y + Height/2) (center) is used for the other objects:
Dist.png

1 Like

Wow nice ! So distance > collision, and distance checked from width()/2 and height()/2 , Good to know.
I’ll test with a lot of objects to see the impact on performance.

Could we have a working example with “false” collision test using this formula ?

Sure!, here is an expample checking for both cases:
DistanceCollision.zip (8.33 KB)

If you want to check false collisions only, instead checking:

A.SqDistance(B) < pow(A.Variable(radius) + B.Variable(radius), 2)

You can just do:

A.SqDistance(B) > pow(A.Variable(radius) + B.Variable(radius), 2)

Ty i’ll test if as soon as possible