I’m working on a relatively big game, and I was messing around with my events while trying to optimize my game as much as possible. I make some changes then run the profiler to see if it makes any difference.
My current understanding:
I know that GDevelop checks the conditions from top to bottom and after reaching a condition that is not met, the following conditions shouldn’t be checked and the event is skipped. At least this is how my potato brain understands it.
The event:
Let’s say I have 10 layers (only 2 in the example) and on each layer there are 10 buttons. I want to run some actions when pressing the buttons ONLY IF the buttons’ layer is visible. I’m testing only one visible layer and the rest are hidden for consistency.
The problem:
In the example below, I tried 3 ways of building the same event. I kept the ordering of conditions the same, so logically the event should take the same amount of time to run right? But the profiler shows different results. Why is that?
The last method gave the best result, however it’s not practical to do all my events like this. Also why didn’t I get the same result out of the 2nd and 3rd methods, they’re basically the same! Any thoughts?
Interesting test. I’m guessing there’s a typo because the 1st is showing the shortest time. I would expect it to be longer because OR conditions evaluate all sub-conditions even if the first is true.
It’s interesting that the 3rd is so much faster. I’d love to know the reason.
I’m curious how a mouse is down condition would test with the other 2 events as sub events.
Mouse is pressed
–layer is visible…
–layer is visible…
When nothing is pressed, the mouse event would be the only event processed regardless of the number of buttons.
There are so many different ways of doing things. Sometimes making easily maintainable, readable and debuggable events is better than the difference of a fraction of a millisecond. Especially if the extra ms isn’t needed. I’m curious how groups and instances would compare.
Thank you Keith for your insight, yes there’s a typo sorry about that. The 2nd and 3rd results are 0.09ms & 0.05ms (I updated the image).
I figured that’s the case, it explains why the first took much longer to process.
I agree. However, I have a lot of events and objects in my game, and I’m working on a good pc, but testing the game on a midrange phone almost doubles the processing times and starts to add up slowing down the game. I’m trying to figure out the best was I can build my events to keep processing times the lowest. Especially with events that process a lot of objects.
Thanks for the tip I didn’t think of it, and it definitely changed the results, a lot. But after some further testing something interesting happened.
When I placed the mouse condition in the same event at the top, the time went down to almost 1/3.
But when I placed the mouse condition it in it’s own event and added the layer checks as sub-events, the time went down to almost 0ms.
This is the same problem with the 2nd and 3rd methods. So apparently, even if the first condition in the same event returned false, there is still some checks happening that are consuming processing time.
I believe this might be a bug and the events should be processed the exact same way.
Here’s the conclusion of my testing and I think this is a bug. (EDIT not a bug)
The processing times should not be different in these 2 events (if not pressing mouse button). Both events should run the exact same way, since the mouse check returns false and the other conditions shouldn’t be processed.
Note: These events are an example and the stated profiling times are from my own game project where I have lots of button objects and layers.
First off… dont count on getting the same ball park results every time… Performance in GDevelop can be extremely random, everything and anything can make it change, even while running the same events…
As for the events them selfs, i can help with that!
The way i see it is this:
Conditions and Actions are just this sort of interface that gets translated into “code” to the engine… this might seems obvious, since its how any software works, but what i mean is, your using a code free engine, but code needs to happen, GDevelop takes your language, in this case “Logic” and then turns it to actual code.
Each Condition and Action translate your “Logic” into different sized “codes”, so for example, “When Key is Pressed” can be a single JS line, while the condition “Or” can be 20 JS lines. (im just making numbers up for example)
Iv been testing and singleing out Actions and Conditions to see their performance, and one of the more expensive ones i came across was the “Or” condition, that you seem to be using on your first test, hence performance being the worse.
The last one is the fastest because it has less to check and run, you have a single condition gateing the rest, iv also found this in my testing, that make a gate with as few conditions as possible will increase performance quite a bit!
At least this is how a see things… well, as far as how GDevelop works, because as far as performance, im 100% sure of what im saying… iv done more than enough performance testing.
Just for some context: Every event box is processed in full, every frame, from top to bottom. Their actions occur, then then their subevents process in the same way (if the parent evaluates true), then their actions, etc.
Your first event will process all of the conditions, even if the first condition is false, because it’s part of the same event box. The final result of the event conditions will be false because the first condition is false, but it still has to go through the full event condition set. Edit: Even if you ignore the “Or/And” logic needing to be processed, it still means it has to build out a list of potential objects to evaluate every time, which is definitely going to take up processing time.
Your second event will only process the subevent if the first event is true. Less to process, therefore it runs faster, and is generally the right way to optimize your events.
You’re right I’m only focusing on events that are process heavy and see how much this affects the over all processing time.
This is definitely the case and makes a lot of sense! I had events that were taking more than 1ms (double that on mobile) each frame when the game is idle.
After I optimized some big events I managed to reduce the over all processing by around 40%. The game now runs at 60fps.
I probably won’t go through all the events. But I’ll keep this in mind while building my events by separating the more heavy processing conditions and add them in subevents to prevent them from checking.