Right, so, I had this brilliant idea! I've been working on this game for...longer than I care to admit right now (we'll cover that in another blog post), and I stepped back, and I looked at it, and I was like, you know what? There's actually a playable game here! Let's get some feedback on this.
So I decided I'd go ahead and release what I had on the LibGDX discord since, well, the game is written on top of LibGDX and they have a whole channel called "play-my-game". Sounded perfect! I spent the whole week leading up to it playing the game and fixing bugs and balancing units and trying to make it the best game possible. Originally I wanted to release on Friday, but well, y'all know how deadlines are 😛
Saturday rolls around, and I'm like, "Ok, let's publish this!" I get the game all packed up and ready to go. But before I push it out, I have this other idea. "Hey! Maybe I should test this on my laptop first. Make sure it actually works on another computer and all that." Welp, that turned out to be a mistake.
I boot up my laptop, and man is it slow. My wife had been complaining about it for a few weeks (but she complains about all computing devices more than a year old 🙂) so I start looking into it. Pull up Task Manager and the CPU usage is at 100%. That's...odd... I look around a bit, and eventually find the culprit. Turns out I have a Lenovo laptop, and in their infinite wisdom, they decided to put some sort of hardware tester bloatware on there. Anyways it was running in the background and absolutely hammering the whole computer to try and see if it was broken. Thanks Lenovo! Oh well, easy to turn that off. I do that and the computer gets a lot faster all of a sudden. Still doesn't feel great, but well it's a 4 year old laptop, what was I expecting?
So I grab my game off G Drive and open it up. Game starts right up, looks great! Let's try playing it a bit and...wow. This game is slow. Like, really slow. I'm moving 10 units around and getting about 15 FPS. Ok, ok, well this is why we test. Let's debug this.
I grab VisualVM on my laptop and try to profile the game. Not sure if I'm just bad with VisualVM or what, but as usual it starts doing weird quirky stuff and crashes the game as soon as I try to get a CPU profile. Works the second time though, so I take a look and...well...nothing is really eating up a lot of the CPU. Typically when you run a profiler on your slow game, there's some function you wrote too late at night that shows up in there as taking up the whole CPU because you accidentally added a nested for loop that didn't serve any useful purpose. Not that I'm speaking from experience or anything here, #justsayin. Ok, well that's weird, but there's multiple ways to find something slow. Could be a garbage collection issue, could be a rendering issue, there's all sorts of things that could be slowing it down.
I check the graphics by pausing the game, which still does all the rendering logic but none of the game logic. I'm getting 90 FPS while the game is paused, so it's definitely an issue with the core game loop. It could still be an issue with the garbage collector, but my game has always generated a ton of garbage and it's never caused issues on this laptop before (optimizing for garbage collection tends to be pretty overrated these days on PCs. You've got to generate a lot of garbage before it becomes an issue).
I go with my gut and decide it's definitely a CPU bottleneck, so I start commenting out my code. I end up removing almost all the game logic except for the movement code. That alone brings the FPS down to 15. Ok, so it's the movement code doing it. But why?
This is the question that consumes my Saturday. I tried everything! I profiled the movement functions specifically, but it was a fairly even spread. None of them seemed to stand out as particularly slow. I added manual timing functions around several functions, but after carefully checking and optimizing them the performance gains were minimal. I recheck the rendering code and remove some of that. I simplify the pathfinding code. I remove the collision detection code. Nothing works! As soon as I start doing anything in the game, the framerate drops to 15-30 FPS.
Finally, around 2 am, I decide it's just gotta be the computer. I never like to blame the computer because any issue you run into is almost always due to something stupid you did in your own code. I decide to go ahead and run a benchmark on it using UserBenchmark just to get a general idea if there have been any major slowdowns in the hardware. I had run the same benchmark on this laptop about 2 years ago, so I had a good basis for comparison.
It runs pretty quickly, so I look at the results and whoa! My CPU has dropped down to the 3rd percentile. I'm not entirely sure what that means, but I'm pretty sure that means it sucks. Fortunately for non-statistic people like me, they have some easy categories up at the top and my "Desktop" performance metric has dropped from "Yacht" to "Surfboard". Ok...that's strange, what could be causing that?
Welp, what's even better about this benchmark is they actually try and detect issues for you. And in this case, they found it! Here's a screenshot:
5%?!?! Why???? To give an approximate reference here (yes I know this is wrong technical people shhh) that's like trying to run my game on a 110 MHz processor. I mean sure you could probably run the original Command & Conquer on that but the original Command & Conquer was also likely optimized by real developers. My own game is very happy being written in modern times as a hobby project where we have obscene amounts of processor power that requires significantly less optimization.
So there we have it. Apparently at some point my wife ran the battery down and Windows or Lenovo or something decided it'd be a good idea to throttle down the processor to 5%, even after I plugged it in and got it fully charged. I switched Windows to the "balanced" power plan and lo and behold, my game suddenly ran fine again. I released it on the LibGDX discord and had no performance complaints.