Help with Optimization

Hi! Lately, I've taken on a new project. I want to make some sort of RPG, and so far it's going decently well. However, the game is fairly laggy, and I've done just about everything I can to improve the framerate. It's reasonable, but I would like to know if there are any ways I might be able to improve it further without significantly changing how the game will work. Here's the link to the project, so anyone who wants to can take a look. I would greatly appreciate some suggestions. Thanks!

(Also, ignore the costumes for the enemy, sword, and player, and how tile collision doesn't work correctly with those costumes. Those are placeholders, and once I have the actual costumes, it will work much better. But until I have them, and know specific dimensions, I can't really do anything else with the tile collision.)

tldr; remove when a pressed block for 2x speed, maybe also clean up all the random blocks thrown about, scroll down for project link

finding performance issues

this probably isn't the usual way people do it and it's not particularly easy but i like to use the browser's built in flame graph for finding performance issues. firefox has a nice performance tab in its devtools that generates an excellent flame graph. if you decide to use it yourself, make sure to close and open the devtools on the performance tab before you start recording. many other tabs seem to put the browser in some kind of debugging mode that makes everything run much slower.

about 30% of the time spent running the project is just on finding, starting, and stopping hat blocks. i'm not too familiar with it, but notably it looks like searching through, starting, and stopping scripts is taking a while.

optimizing

first thing i did was removed all the unused blocks. snap can go through all the scripts for hat blocks faster if you get rid of all the script without hats. only about a 2% improvement.

next thing i did was remove the when a pressed from tile, and replaced it with a waiting loop tacked onto the existing flag block

this stopped all the hat block checking entirely, and the project is nearly twice as fast.

i'm not happy with the performance still so i'm going to keep messing with it but i figure this is enough of a difference that you'd want it now:

i'll probably make more posts with better performance changes later

other

on another note, are you using empty loops to wait out frames? i'm seeing them all over the place, and plenty of WAIT 0 SECS blocks.


i don't know the specifics of the new quicksteps update (when exactly it does or doesn't run loops fast), but that might've broken these?

tldr; use less blocks per frame. tile clones are running too many blocks, and could be running none instead. put stuff in variables before your loops, including rings. clones keep the local variables their parents had.

finding the next performance issues

as a rule of thumb, blocks in snap are slow. except for special operations like stamping or colliding massive costumes, the amount of time spent per frame is pretty much proportional to the amount of blocks ran per frame.

because of this, the next place i went to was the tile sprite, because 700 clones all running a script in a loop means that script is 700x more important to slim down, and the tile script was quite bulky.

optimizing

clones keep the same local variables as the parent when they're created, so just setting the variable in the parent sprite is faster than telling the clone to change it afterwards.

hyperblocks (putting lists into blocks to get a list as output) let me throw out the many many number key checks, and made position math faster and easier to work with.

storing the tile in a local variable instead of grabbing it from the map list let me cut out many long map checks, and storing the position beforehand let me cut out all the recalculating that involved.

i moved the editor out of the tile clone and instead turned it into a script without a hat that runs on the main sprite. instead of every clone checking if it needs to change, the main sprite tells the clone that it needs to change.

after this, the leftover clone code was so small that it would've been slower to check if it was on screen. snap checks if sprites are on screen or not before rendering them anyways, so no real difference there.

since at this point all that the tiles did was move based on the camera, i set them to use the parent sprite as an anchor, so that they move automatically.

since i made changes to the local variables in the tile sprite, i went into the player and enemy sprites and cleaned them up a bit, notably the tile collision code no longer needs to check the map, since the tile has a local variable for it.

results

by my measurements these changes make the project about 3x faster, combined with the previous for a total of 6x.

Wow! That's an incredibly large difference! I'm going to try to implement this into the copy I have. Thank you so much! I haven't really touched the anchoring of sprites, but I didn't realize that could make such a large difference.