Orkn's Pulp Prototypes

Nothing new to show (it looks and plays exactly the same) but I think I've reached the end of my current performance optimising of Lolife.

Before any optimisation I was losing about one frame per second for every entity on screen:

0 entities = 20 fps
1 entities = 19 fps
2 entities = 18 fps
3 entities = 17 fps
4 entities = 16 fps
5 entities = 15 fps

After optimising it's still not perfect, but it's a lot better:

0 entities = 20 fps
1 entities = 20 fps
2 entities = 20 fps
3 entities = 19 fps
4 entities = 19 fps
5 entities = 18 fps

How I got there was with a whole mix of changes.

Minimising use of draw and label

In addition to the "fixing" of off-grid labels in my post above, I baked in the health/target/experience bounding boxes to my rooms, bringing my labels per frame down to zero and leaving me with just three fill calls per frame.

Minimising swap and frame

In my first post on Lolife I shared how each enemy was a single sprite with multiple frames for each direction they can face. This was very neat and tidy but meant I was calling both swap and frame each time the enemy moved. By splitting each direction into a separate sprite I only need the swap.

This also solved a bug I found in enemy attacks and simplified that code as now I just use play for the enemy attack animation.

Minimising event calls

I managed to rewrite my way to an extra frame per second just by changing my "pick a random available direction" code from calling several events to just calling one. I'd suspected as much from when I had to change my line-of-sight code in Resonant Tale, but this confirmed it - calling events is not performant. I don't know why, but splitting code between events is not a good idea for performance (which is disappointing, because it's much neater to do that!).

Once I'd confirmed it was worthwile I rewrote a lot of my code to try and minimise the number of events I was using. Along with optimising the HUD this had the biggest impact!

Minimising scripts involved

In addition to event calls being slow, it seems like just telling another script to call an event is slower than calling that event in the same script. Again this is a bit annoying from a keeping tidy code perspective, but I needed all the savings I could get so I went ahead and moved most of my events and code into the game script. I went from events in the game script calling an event on the enemy sprite script calling events on a generic behaviour sprite script, to just calling events in the game script.

The enemy sprites now don't have scripts at all - which is actually quite neat now that I have split enemy directions into separate tiles.

Minimising variable assignment

This probably had the least impact, but I managed to optimise some of my code by being smarter about what variables I was using and the operations involved.


Overall I'm happy with the peformance now. A drop to 18fps is a lot less noticeable than a drop to 15 (and actually not really noticeable at all with pulp's tile based movement).

Received wisdom in software development is that premature optimisation is the root of all evil. While I haven't yet made much of the game, this optimisation wasn't premature - knowing the limits of the number of entities I can have on screen will inform my game design!

3 Likes