Is C2/C3 good for large 2D desktop games?

Discussion and feedback on Construct 2

Post » Sat May 27, 2017 9:55 am

Something I always wondered regarding optimisation... what is the best practice for organizing event sheets? Or rather, does any of the approaches make a huge difference, performance or otherwise?

Let´s say I make a game with several layouts and 1000 enemies, each with individual behavior. Now my personal approach on this is to make an event sheet for each enemy, and use includes in the layout event sheets to only use the enemies I need. So a layout that only uses enemy #874 will also contain only that part of the code. Everything is neatly organized and I´m pretty sure that is the definitive approach for it. (right?)

Now my question is, if I were to make one single event sheet that contains all 1000 enemies (sounds like code-hell) and include that monstrum in my layout event sheet, again for a layout that only uses enemy #874, how are the events handled then? From what I understand is that the event system will first go through the conditions for enemy #1-#873 (top to bottom, excluding sub-events) and then finally reach the only enemy that is used. Wouldn´t this impact performance? Or is it not even checking the conditions since the layout does not contain the instances? (Isn´t this a check in itself, to see that there is no instance?) If it does impact performance, it should be mentioned in the Performance Tips.

Now a different situation. I (actually) create a single-screen app. The app can have different states/pages that are currently active, and based on the current state a set of events should run. Since it is only one layout, it needs to include all the code for each state/page. But obviously if I´m on page 3, I don´t need to run the events for the other pages. I handle this by using a state machine (If you haven´t heard of it, google it right now and thank me later :!: ) So it only needs to do very simple checks (state 1, nope. state 2, nope. state 3, yep) However, I could also use the ability to enable/disable groups, I assume this would theoretically be faster, since it doesn´t even have to check anything and only runs the enabled group, but only by a miniscule amount. (right?)

And now a last question. The event system works top to bottom, and once it worked through all events, it makes the drawcall. This is one tick. But doesn´t that also mean that on a sub-tick level, nothing is allowed to happen at the same time? I´m pretty sure in certain cases this would heavily compromise stability, but in other cases where it doesn´t matter, would it speed up the process? So instead of "Do A, then B, then C, then D" it would be "Do A, B, C and D". Now even if it would speed up, it´s questionable to sacrafice stability to squeeze out 0.0001 fps, but maybe for bigger projects it would actually improve for 3-5 frames and might be worth it as an option. I imagine a sort of "Run simultaneous 'tag'" condition, aswell as a "Run simultaneous events with tag 'tag' now". That would allow stuff to run simultaneous while still beeing somewhat controlled within the event system flow.

Or maybe I just have too much time to think :|
B
16
S
3
Posts: 69
Reputation: 1,048

Post » Sat May 27, 2017 12:30 pm

The best practice in organising your events sheets is to keep things organised from the get go. Put things into groups logically and don't forget you can have groups within groups.

Leave yourself plenty of comments too - even for things you think are simple. Sometimes if you have to stop for whatever reason for a week or so, without good comments you are going to feel pretty lost getting back into a big project.

Forget about trying to optimise your event sheets for performance. Truly, it is not about how many events or event sheets you have - it's about what you are doing with those events. The debugger shows you where the events are that are potentially problem areas (or at least areas that you can improve performance through optimisations).

If you are creating a big game, 2 crucial things to look out for are;

1.) that you aren't overloading the gpu with too many art assets (this means building large landscapes from smaller parts that you will re-use heavily the same way all 'big' games do but you might not realise).

2.) you don't have the cpu doing unnecessary work (think of it like making sure you have turned off the light after you leave a room to save electricity). The real question is, is it possible to do this for the game you are imagining? If not you might have to make some compromise.

@WackyToaster re your 1000 enemies, do these 1000 uniquely acting enemies share parts of their behavior? I have no idea what type of game you are making but that seems to me to be a bit overkill. You should try to make universal behaviors that can cover a wide range of functions/behaviors instead of creating specific ones for each whenever possible.
ImageImage
B
128
S
23
G
7
Posts: 1,076
Reputation: 13,226

Post » Sat May 27, 2017 12:34 pm

@WackyToaster - what I've learned in my experiences is that ESPECIALLY if there are no instances of the enemies - it will consistently run all code checks pertaining to the non-present enemies.

What I do is create a spawner for each enemy, and at the start of a layout I check if the spawner exists. If it does, I enable the group for the enemy code and create the enemy per each spawner. If it doesn't exist it disables the group.

This way you don't have to worry about it running code for nothing as well as making easy changes to your enemy without having to do them in every layout or in code.
B
41
S
12
G
1
Posts: 540
Reputation: 4,188

Post » Sat May 27, 2017 12:51 pm

I have no idea what type of game you are making but that seems to me to be a bit overkill.

I should have made it more clear that this is just an example, I don´t actually make a game right now, just an app. :) It was just exaggerated to show my thought behind it, that the event system will go through all other events even if they are not in the layout, before getting to the one event that matters, thus eating performance for nothing.

what I've learned in my experiences is that ESPECIALLY if there are no instances of the enemies - it will consistently run all code checks pertaining to the non-present enemies.
What I do is create a spawner for each enemy, and at the start of a layout I check if the spawner exists. If it does, I enable the group for the enemy code and create the enemy per each spawner. If it doesn't exist it disables the group.

Sounds like a good and easy approach to me. Not having to think about all the includes would make it even easier.
B
16
S
3
Posts: 69
Reputation: 1,048

Previous

Return to Construct 2 General

Who is online

Users browsing this forum: No registered users and 5 guests