Wednesday, October 29, 2014

Math Optimizations

I've been avoiding optimization for a while now.  I used to think optimization was the secret to life, but then I listened to a lecture by Jonathan Blow where he said that it's rarely necessary when we think it is, and it takes forever to do, so it's usually a waste of time.  However, after reading through Christopher Park's (developer behind AI War: Fleet Command) blog, I've decided to optimize just a bit before I move forward.  Because Sever's AI will work similarly to a standard RTS, speed is of the essence.  I need the AI to think fast and not lag too far behind the human player.  Also, these optimizations should keep things synced between clients in a multiplayer game.

First off, I changed the primary data type that I was using for all of the math.  I was using the float datatype because that's the default type used in MonoGame.  If I was more educated, I could probably tell you why.  But alas, I'm not.  Anyway, Christopher Park had an issue with syncing and created a truly fixed-point struct that apparently did the trick.  Rather than waiting until I have syncing issues, I decided I'd start early and do the same.  It took a bit to get it working correctly because I had to go through every single stinking class in the game and change Vector2s to my new VectorF struct and floats to the new FInt struct.  I also made some modifications to his version of FInt to make it do what I wanted it to do.

If you want to know more about fixed point math, look here.

I got it working, and I haven't noticed any performance improvements, mostly because as an early prototype, it rarely goes under 60fps anyway, which is actually probably too high.  I'll probably lower it for the sake of processing power.  60fps is more important for shooters and stuff like that.  RTSs can sacrifice a bit to make room for non-graphical processing.  Anyway, I trust that using fixed point math will help out in future versions, whether I notice it or not.

Also, he talked about distance approximations.  Square roots are slow, and finding the distance between two points requires a square root.  Finding the distance between a point and a line (a common operation in Sever) requires 4 square roots!  When drawing graphics, you need exact numbers, but when doing collision testing, you can first use an approximation, which is enough to tell if the points are close enough to do the real distance calculation.  In the end, that's more math, but 90% of the time it doesn't get past the approximation, so it really saves time when doing collision testing against a hundred objects, most of which are far away and don't need precise calculations to know that they don't collide.

If you want to learn more about distance approximation, look here.

While I'm not sure how much I'll notice a difference in performance as a result of the switch to fixed point math, I'm pretty sure that the distance approximation is going to make a big difference in both collision testing and path-finding.  In both, there's usually alot of wasted distance calculations, so this should soften the blow to performance quite a bit.

That's all that I've done since my last post, besides play against the AI over and over.  Hopefully my next post will be more interesting.  Thanks for reading!

clevceo

No comments: