I got some great help on this board the other day. Suggestions about lerp and garbage collection made a big difference in improving performance in my mobile game. I was curious if anyone else has any optimization tricks or things they tend to look at/adjust when getting a game ready for mobile in 2018.
Isn't garbage collection done automatically? Can you force it in Construct project and does it make any difference?
I learned that effects are slow. (at least on a mid-range Android phone). If I add any effect to even a small sprite in my mobile game, I'm immediately getting a drop in performance. With 10 sprites the fps can drop to under 30 and the game becomes unplayable.
Same with "Force own textures" settings on layers. Each layer like this subtracts 5-10 fps.
Develop games in your browser. Powerful, performant & highly capable.
I thought garbage collection was handled by Construct also, but after someone suggested looking at it I gave it another shot.
My auto runner was plagued by a periodic jank I couldn’t correct no matter what I did. I had a lot of little instances in my game of objects being created or destroyed every few seconds. I also had a lot of sprites I preloaded off-screen then destroyed. I modified my code so the game would load everything it needed to use immediately, and then instead of ever destroying anything, it reuses the same objects over and over. My problem appears to have been garbage collection stutters as the game adjusted itself to each creation and destruction; now the issue has completely vanished.
That got me wondering about what other little tips people might have.
These are some of the performance related things I think about when developing games...
With your art keep in mind the power of 2 (32, 64, 128, 256, 512, 1024, 2048), as images are decompressed and often processed as power of 2 images, and if not already at power of 2 will use the next size up.
E.g. A 513x513 image will process as a 1024x1024 which uses 4 times as much as graphics RAM as 512x512
Anything below 256 is generally fine as they don't take up much memory, but above that you'll want to think carefully about sizes.
It's not as much of an issue with PCs and dedicated graphics cards, but is important on mobile.
https://www.scirra.com/blog/112/remembe ... our-memory
Use triggered events, functions and Timer behaviour instead of checking/setting things every tick. E.g. On Touched/Tap Object, instead of Is Touching Object
Frequently updated text, e.g. score/counter/timer, should use the SpriteFont object instead of the Text object, as the Text object lags a bit if updated every tick.
Turn off collisions for objects that don't need it e.g. background and GUI objects
Don't have a platformer object offscreen falling into eternity - I forgot to delete one once and got bad performance as it kept changing render cells every tick
[quote:2oqceny8]Turn off collisions for objects that don't need it e.g. background and GUI objects
This is not really necessary. Construct only performs collisions checks for an object if there are relevant events or behaviors.
If your background sprite has no behaviors like Solid or Physics, and is not part of "on collision"/"is overlapping" events, it will not generate any collision checks.
Here are some things I've learned:
1. For events that you only use a small % of the time, (i.e. Menus), disable the groups when they're not needed. It can save a lot of CPU depending on how intensive it is.
2. The dreaded for each loops. I had a lot of trouble for a long time fully understanding them, but here's a good way to utilize them for the best performance.
If you have a Boolean "isAttacking", you can do
if Enemy.isAttacking; For each Enemy; <insert actions>[/code:3b5vrw7i]
As opposed to having the for each before the check (for some reason that takes a HUGE amount of CPU even if they're not doing anything)
That might seem obvious, but whag really kills performance is using for each before an overlap check (which I always used to do)
3. Try to avoid every tick events as much as you can. If a health bar is being set, set it to update on a trigger (or when you are hit; use functions). If you have to do something every tick, ask yourself "can this afford to be checked every 0.1 seconds?" This goes for checking variables, overlaps, collisions. It might not seem like a lot, but it adds up quickly.
4. Avoid large images (a single 1920 x 1080 background is fine for a steam release, but add a few more and people will start complaining about fps issues). I can't comment too much about phone performance.
5. Careful with overapplying the fillrate. This means having layers on top of layers on top of layers (if you have a background image, then I tilesheet for walls, then a mother tile sheet, for the floors, then another tilesheet for x y and z, it'll start to slow the game down when things are moving).
6. For tilemap a specifically, they're only useful if you're actually tiling (so if you have 3 tiles that you want to use as your floor and you want them built at random, a tilemap is the wrong choice - each tile that is not connected. basically has to redraw the Sprite (might save on objects but not on drawcalls)
7. I've yet to figure out an efficient way to do this, but for larger layouts with thousands of objects, you can destroy objects outside of the players view and recreate them every second or so. Use with caution, however, because depending on how many objects there are, it might pause the game a frame or two to create them.
8. Use families as much as you can, but also use with caution. If you have 20 bullets in a family and 300 enemies in another family and you check an overlap with 1 bullet on the screen and 2 enemies in the layout, for some reason it'll check through every non existing enemy and bullet in both families. There are ways around this, however (either using a Boolean on created and checking that before you do the overlap and for each - I think...)
That's all I can think of off the top of my head. Hope it's helpful to someone!!
This is all great. Thanks, everyone, for responding in such detail. I’ve seen optimization articles by Ashley in the Construct 2 manuals, but I don’t know if anything definitive has been compiled that reflects the latest technology conditions. I can’t help but wonder how many other tips/tricks/optimizations have been discovered as people push the engine in different ways and for different formats. I’d be very interested in seeing some kind of community style census to pool the best tidbits from everyone’s experiences. I have more to reconsider in my own project just from these posts here. Thanks again.
Nested loops are something to avoid if you can.
Every tick doesn't slow the game down, as it doesn't actually do anything. The event would be the same if you removed that condition. "Every tick" functions as more of a title than an actual condition.
If your goal is performance, the only things you can really do to improve it is to optimize your code, with almost no redundancy, and loops only when necessary, and don't use big images. If your image looks too pixelized, use an effect to smooth it out. Memory is one of the biggest concerns, especially on mobile. Typically the processors and graphics chips on mobile devices are decent enough to handle a fair amount of processes and effects.
FWIW our latest performance advice is in the C3 manual: https://www.construct.net/make-games/manuals/construct-3/tips-and-guides/performance-tips
Thanks, Ashley, I am looking through it now. There's a lot more room for fine tuning than I thought.
P.S. I really enjoy Construct. I've had a personal license for 2 and now 3 since last summer, and I've found it to be by far the most user friendly development kit I've tried.