Performance is a hell of a thing. Chasing it is as close to being addicted to drugs as I can imagine. Your always chasing that last tiny bit of it and it has you doing more and more crazy things with ever diminishing returns. Here is how I spent 96 hours chasing my last high.

Preface:

MAVs are expensive. MAVs on screen are VERY expensive. But worse, they are expensive just existing in the level. How expensive? Well, in my baseline test, 12 MAVs ate up 60 milliseconds of CPU time, not including the actual drawing of them on the screen. Considering I am looking to be at 16 milliseconds for the whole game, this was a problem.

Time to dig in.

It’s easy to say MAVs are expensive. Just spawn a bunch and watch what happens. I needed to know WHY are they expensive. Time to fire up the profiler! I jumped into 12 man games and watched as the profiler gobbled up all the data and drew all it’s pretty charts. I compared multiple plays on multiple levels, with different MAV makeups. This allowed me to eliminate specific MAV design issues or issues unique to a level. After a few hours I was able to create a hit list of the top offenders.

MovementCode – 12 ms AnimationUpdates – 23 ms AimingCorrectors – 8 ms AttachmentCorrectors – 1 ms Ground Alignment – 1 ms

These top 5 offenders are worth 45 ms of CPU time alone!

Testing:

This is what this stage looks like

I created test levels with just legs walking in circles. I added spinning parts to them. I tested having the parts attached in a nested hierarchy versus a flat one. I tested just about every possible thing I could thing of. The more testing I did, the more apparent the looming problem was.

Unity hates how I build MAVs.

There was no getting around it. Unity fundamentally did not work with how I was assembling a MAV together. The most basic building block of the game and I had somehow done it the ‘Wrong’ way. Great. Time to throw in the towel and rewrite the whole game. I mean right?

Or, to quote Matt Damon, “It’s time to science the shit out of this”.

To Science!

Or more so the scientific method. I spawned in a MAV and manually rearranged it, or tweaked a value, or twiddled a switch, logged the change in performance, then collected the data. I did this for exactly 148 different tests. I was chasing performance and I had to find it. And find it I did, in the most unusual of places.

Off with it’s head:

In my data logging I found several key points. Unity hates having a physics object attached to an animated object. Even worse if it’s a dynamic physics object. Unity also hates deep hierarchies. It seems Unity was written with less than 10 levels of nested objects in mind. Unity even more so hates rigidbodies being children of other rigidbodies. I was doing all of these things and unity hated me. In one test, I happen to remove the entire top half of the MAV as I was moving things and I noticed a MASSIVE increase in performance. So that is what I did. I chopped the MAV’s in half.

The Reattachment:

Chopping things in half is super fun, but for the game to actually work, we kind of need that top half back. I tried many different ways of doing this, the result of one can be seen below, but ended up having to go with a solution that was not as performance friendly as some of them, but actually provided the same game experience currently in MAV.

Results:

After fixing up some code that assumed your MAV was all 1 item, I had my results. What used to take 45 ms, was now taking a smooth 16 ms! A more than 50% decrease in CPU time!

MovementCode – From 12 ms to 3 ms AnimationUpdates – From 23 ms to 6 ms AimingCorrectors – From 8 ms to 0 ms! AttachmentCorrectors – From 1 ms to 7 ms [Lots more correcting now] Ground Alignment – From 1 ms to .5 ms

I have predictions that I can even reduce that more! It’s possible that with a more extensive rework I could save another 5-8 ms. This will need to be done for the eventual goal, but it’s time for me to move on to other problems for now!