Network Diversion

In my head, QubeKwest is always a client/server program.  Meaning that even a single player local game is going to be the client program connecting to the server program over localhost.  The fun part there is that it means that the client and the server can be located anywhere.  On a powerful computer, they talk to each other over a localhost network with both parts running on the same computer.  On lesser computers they talk to each other over an actual network with the client and server each being their own computer.  And in the case of playing with your friends, they talk to each other over the internet.  If I code it right, the game not only “won’t care” but it actually won’t even know the difference.

Networking is a tricky beast and starting with the server makes the most sense.  A server can be coded in tons of different ways I’m sure, but the two that I have personally coded are the threaded approach and the asynchronous approach.  The threaded approach just uses the normal java.net.* things while the asynchronous approach uses java.nio.*.  If you’ve ever tried to code your own NIO version without help and pulled it off you are better at coding than me.  Simply put, I get the java.net.* stuff and my brain skips a step and stumbles the rest of the way down the stairs to end in a heap at the bottom when I try to understand the java.nio.* stuff.  Ok, that’s not fully true anymore, but it certainly was for previous attempts.

For a little background on the differences between the two approaches, I present a couple of paragraphs that get a little deep.  In the threaded approach, your server has a full blown operating system thread to handle every single incoming connection from a client, and another one to act as the server thread itself.  This is extremely heavy, not terribly scalable, and puts a pretty hard limit on the number of clients that can be connected at the same time.  Most modern operating systems support thousands of concurrent threads, but long before you get anywhere near that number, you start slamming into the overhead of switching between the threads you are using.  This approach is easy to code, easy to understand (if you understand how to play nicely with threads at least), and completely useless for large numbers of client connections.

In the asynchronous approach, you create a semi-magical server with just a thread or two to handle all the work of responding to clients.  The magical part is that it doesn’t matter if there is one client connected or 1000, the number of threads the server uses to manage the whole thing doesn’t change.  For a most excellent explanation of how this works, go check out the Rox Nio Server Tutorial.  I used that tutorial to craft how my game server works and it is the best description of how to make Java NIO stuff work correctly that I’ve ever bumped into.  This approach is a little trickier to code, vastly more complicated to get your head around, and scales well since you don’t need tons of threads to make it work.

This brings me to my diversion.  In all of the refactoring and playing with and confusing things and in general just blowing up of code that I did while writing an NIO server for QubeKwest, I managed to entirely lose track of how to use it and then I managed to substantially break it.  After seven months without looking at the code, I came back to discover that my network code was well and truly busted and that I had no clue how to fix it.  I started trying to follow the Rox Tutorial again on the code I had, but quickly found that my code was so different from the original that even that wasn’t useful.

Then an idea popped into my head.  Start over.  I know, great idea…  but sometimes it’s just what you have to do.  In this case I decided to simply make a stand alone server that wasn’t connected to the QubeKwest code at all.  This approach eliminated the QubeKwest package structure, the broken code, the refactors I’d incorporated, and it allowed me to learn how the whole thing was supposed to work again.  All without further destroying the networking in QubeKwest.

It took me a couple of days to get it to work properly because I was taking my time and making sure I understood the code I was writing.  When I thought I was done, I found that I was exactly one line of code short of having it work properly.  The code I’d produced was pegging an entire CPU core to 100% (even without requests coming in) and didn’t respond to the client.  This is obviously not an ideal server since the goal would be to use essentially 0% of the CPU unless you are responding to something and of course to actually respond to things.

Once I found the one line of code I’d missed, added it in, recompiled, and fired it up again, everything was suddenly behaving correctly.  Now I just need to refactor the code a bit in the stand alone version so it is a little cleaner, and then start integrating it into the QubeKwest network package.  It was an interesting couple of days, but at least I learned something and have functional code again.

 

Resuming Development

So there I was, completely stalled on QubeKwest for roughly seven months.  Sure, I thought about it from time to time, but that never managed to inspire me to actually work on it.  Naturally that means that thinking about it tended to make me a little sad.  The cycle continued and the project languished.

Then a couple of interesting things happened.  I started to realize that part of the reason I was never working on QubeKwest was that I would come home from my normal job and not be able to find the motivation.  I even mentioned that in one of the previous posts on this blog so it was clearly something I was aware of at least subconsciously.  A few things happened at work that made me blindingly unhappy with the company I was working for and it hit me like a ton of bricks.  My job was making me miserable.

There are a couple of paths you can choose to follow when you make a realization like that.  You can complain about it, a lot, to everyone that will listen.  This approach tends to not make anyone any happier.  You aren’t solving anything by grumbling and your friends get sick of hearing about it.  This path tends to be the one used early on before you realize the depth of the problem you are complaining about.

The second approach is to do something about it.  This way is hard.  At least partially because change is hard and not many people (myself included) like change much.  It is however the only way to actually solve anything.  My eventual solution was to find a new job.  This didn’t immediately provide me more time to code QubeKwest, but it did immediately improve my general happiness.

Now, as a happier guy in a new job, I still wasn’t fully motivated to start development again.  At this point, I honestly hadn’t even thought about QubeKwest in a while.  Then something happened that made me immediately think of it.  The Raspberry Pi 3 was released.  I got to thinking, “Hey, I was totally going to try to get QubeKwest to work on a Raspberry Pi 2 and now a new one is out.”

As the proud owner of virtually every model of Raspberry Pi and someone that was very impressed with the new updates to the Raspberry Pi 3 (now with 64-bit CPU, and with built in WiFi and Bluetooth!) I immediately ordered several of them hoping they would be the last little nudge to resume for real.  Or, if not the last little nudge, at least a nudge in the right direction.

The Raspberry Pi 3s came in and instead of starting development again I was inspired to reinstall Windows on my main development machine.  Long story I won’t bother telling, but it needed it.  That took almost a whole weekend.  I was still a little nervous about starting again but I was starting to have fewer and fewer excuses.  I hadn’t looked at the code in seven months and that meant trying to figure out what I was working on and what the heck I was thinking when I wrote that piece and where I go from here.  But at least now I was ready.

I fired up Eclipse, I got annoyed at Eclipse, again.  I started the hunt for another IDE.   I grabbed IntelliJ IDEA and I like it so far.  Last night I attacked the code for the first time and I found there were loads of things I needed to fix.  I grabbed the latest LWJGL, but they had moved things around and renamed things and removed things so I had to fix my code to line up with their code again.  I also had to figure out how to fix the various broken bits of code that I’d checked in when I put the project to sleep seven months ago.

After about an hour, I had a shiny new IntelliJ project set up, I had my external libraries configured, I had the worst parts of my busted code commented out or repaired, and I got my ugly red triangles back on the screen.  I was in business again.  I think the first thing I need to do is revisit the extremely sad network code and try to figure out what I was doing there.  I am going to officially call that a plan!  Let the coding begin.