Ask here your questions to get help using GDevelop.
User avatar
By sleeper_service
#63095 Tip: End Complex Conditions Early

I didn't really find any threads or informations on this, so I though this might be worth pointing out.
Image
HDog's performance took a noticeable dip after the last alpha update. I tried some stuff and it looked like events where the main offender. (Changing all assets to not be loaded in memory didn't do much for example). At some point you might need a lot of complex events to control complex stuff all the time and HDog has that in the form of all the enemy behaviours.
Example one shows the fighter AI events that put noticeable stress one the system. But wait, example two is for another enemy that simply never existed during the test run. So all this events grouped under "hostile gunship behaviour" still run in the background and stress the system. Example three fixes this by checking first if the object that the group deals with exists at all. Example one could probably also be made less stressing by putting the easy, often false conditions into a parent event.
Maybe this is helpful for people dealing with performance issues in projects with a lot of complex events running at all times. :) :?:
Last edited by sleeper_service on Tue 22 Aug 2017, 15:29, edited 1 time in total.
By Kink
#63103 Personnaly i always limit loop and condition. A condition only if it's related events are created previously, and for AI, that could use a lot of ms in the render when there a lot of ennemy, it triggers only on a distance conditon in a "for each" condition.
Each object that is supposed to act on screen is disabled when it's 1500px out of the screen.

I always cheeck the performance monitor and my aim on the game is to keep the render time of the scene under 20ms in any case.
A little tips, but potentially great with impact if you have a lot of code : add "do once" everywhere it's possible. On my first big project 3 years ago, i've saved 80% of performance with it : it's not needed to process the same action at every frame.

Last tips : variable display (UI) refreshing : fast changing values (text/number) with multiple text objects on screen can have a big impact on perf. I figured out that it doesn't need to be refresh at everyframe, and not all at the same time, so i use a chronometer (or better custom chrono with TimeDelta()), and all the refresh of the text objects are at different tempo : one is trigger at 0.25sec, the second at 0.5, the third at 0.75, etc. and then the i restart the chrono. I saved a lot of performance using this tips.
User avatar
By sleeper_service
#63109 Nice! That was super helpful to read, if you got more advice I'd love to hear it. (Changed the thread to serve as an optimization tip compilations, maybe others can tune in too)

Kink wrote:add "do once" everywhere it's possible. On my first big project 3 years ago, i've saved 80% of performance with it : it's not needed to process the same action at every frame.
Right, this gets difficult if you need to apply the action to multiple objects that might meet the condition simultaneously. For individual objects I switched to states that get changed first as the action ins applied, that essentially acts as a "do once for each object", but requires and additional albeit cheap condition.

Kink wrote:Last tips : variable display (UI) refreshing : fast changing values (text/number) with multiple text objects on screen can have a big impact on perf. I figured out that it doesn't need to be refresh at everyframe, and not all at the same time, so i use a chronometer (or better custom chrono with TimeDelta()), and all the refresh of the text objects are at different tempo : one is trigger at 0.25sec, the second at 0.5, the third at 0.75, etc. and then the i restart the chrono. I saved a lot of performance using this tips.
Would be interesting to see here how stressing changing a variable continuously is by itself, since that could also be striped down to your chronometer system for each and every variable in game. Question is whether "pick every" for all the stuff you might want to updates its variables might be stressing again.

Also another question: From your experience, what are the most stressing conditions and actions the event editor uses?
By Kink
#63122
sleeper_service wrote:Also another question: From your experience, what are the most stressing conditions and actions the event editor uses?


It depends on a lot of things, but basically it's really chronometers : i don't use anymore actions and conditions related to this, i only use TimeDelta() custom chronometer, wich is really lighter. I also avoid to use mutliple chronos, sometimes you have to create one for each objects when it's AI related, but for some case, a global chromometer is enough for multiples things (refreshing UI for example).
Refreshing text is really stressfull if you have a lot of values : it's not always related to the game, but i use a custom "debug feature" in my projects to display every parameters of objects in realtime, and it's really stressful if you have a lot of objects, so it's needed to limit text refresh.

There is no action really stressfull, it always depends on the numbers of objects affected, and the complexity of the script. I really often make stress test : for example, i spawn 400 enemy entities and look how does it react ; i check in realtime each loops and group of events, and i try to reduce it to the maximum with the tips i given previously.
The most consuming things that i saw is using a lot of concatenations in variables conditions, used in sub event, sub event, sub event in a "for each" main loop, but there is nothing you can do on it. I'm also a bit "mad" with it since i use it a bit like SQL with tons of structures variables :D

Performance on events is something, but you should also take a look on global ms for the display render (and fps of the game wich can drop sometimes) : using particules extensions for explosions for examples can create fps drop (with too much particles/objects created). Optimize your images, for both sprites/mosaic/particles, don't use png and transparency when it's not needed, optimize your png with tools like Tinypng to reduce the file weight (and destroy useless pixels information that even photoshop/gimp keep : transsparent pixel aren't deleted, they just have maximum alpha channel value set).

Also, and last tips, i always chase for undeleted object : sometimes and i've never figured how/why, some object that should be destroyed aren't (for example you destroy an ennemy, destruction generated 3/4 objects (explosions/lights/etc.) or even your projectile). In the order of event, it should be destroyed, but not.. it's often related to particule objects, and even if you have picked "self destruction" of the object when the capacity number of particles is over .. For it, the only solution is to check the debugger objects list, and after try different order/sub order for the events.

I hope this will be helpful. For now my projects are sleeping because of the bug i've spotted few months ago. I always have memory leak problem in IDE preview, and it's related to external events.... i'm waiting for new Gdevelop version to support native games.
User avatar
By sleeper_service
#63126
Kink wrote:Also, and last tips, i always chase for undeleted object : sometimes and i've never figured how/why, some object that should be destroyed aren't (for example you destroy an ennemy, destruction generated 3/4 objects (explosions/lights/etc.) or even your projectile). In the order of event, it should be destroyed, but not.. it's often related to particule objects, and even if you have picked "self destruction" of the object when the capacity number of particles is over .. For it, the only solution is to check the debugger objects list, and after try different order/sub order for the events.
Yeah I use global obliterate events between enemy waves, as far as I can tell those catch everything, with most objects having self-destruct conditions already beforehand.

Kink wrote:It depends on a lot of things, but basically it's really chronometers : i don't use anymore actions and conditions related to this, i only use TimeDelta() custom chronometer, wich is really lighter. I also avoid to use mutliple chronos, sometimes you have to create one for each objects when it's AI related, but for some case, a global chromometer is enough for multiples things (refreshing UI for example).
With chronometers you mean timers thne? Is till use those a lot... good to know that they should be better stripped down. Do you know if pausing unused timers does help?

Kink wrote:I always have memory leak problem in IDE preview, and it's related to external events...
I have that too, but the compiled games seem to be unaffected. GDev also crashes a lot if I preview stuff after making changes to large event sheets, I got around that by almost always working in a small sandbox sheet now.

Kink wrote:I hope this will be helpful.
Most certainly, thanks a lot!
By Kink
#63127
sleeper_service wrote:With chronometers you mean timers thne? Is till use those a lot... good to know that they should be better stripped down. Do you know if pausing unused timers does help?

Yes timers sorry ^^ idk for pausing timer, but i suppose yes.

sleeper_service wrote:
Kink wrote:I always have memory leak problem in IDE preview, and it's related to external events...
I have that too, but the compiled games seem to be unaffected. GDev also crashes a lot if I preview stuff after making changes to large event sheets, I got around that by almost always working in a small sandbox sheet now.


Ha ? Good to know i'm not the only one, also i'm working with 4.0.92 only, the 94 was too buggy and also have the bug. Did you reported it yet ?