Saturday, December 31, 2011

Farewell, 2011!

Here we are at the end of an amazing year. Team Laser Combat has come a long way, but not nearly as far as I'd hoped in the beginning. Thankfully, many of those delays were caused by very good things, such as:

  • The Global Game Jam.
  • The Game Developers Conference.
  • The birth of my son, Avery.
  • Teaching several new courses in an ever-changing curriculum.
  • My mad dash to finish my masters degree (almost there!)
  • Traveling to visit our families for holidays.
  • Our fourth wedding anniversary.
  • And many more good things.

Man, it's been a great year!

So Where Are We?

Well, with all of the events going on this week, I haven't had a whole lot of time to devote to fixing the defects mentioned in my last post.  In fact, I seem to have made them worse instead of better.  But that's OK -- I've made another radical decision that seems crazy but is almost certainly good for the end result.

Character movement is the most complex thing I've implemented so far.  I originally had it working well for local clients, but it was unreliable for network clients.  My solution was a compromise between something that worked well and looked "just OK".  Now that most clients are local clients, I'm going to return to my original algorithm but change the way the network messages are sent and handled. It'll look better and it should fix the character duplication bug that I mentioned in my last post.  (Besides, it'll allow me to prototype something that will be needed in my next collaboration, Botz.)

What's Next?

So the next steps, which will begin 2012 for me and TLC, are as follows.

  • Improve the character movement algorithm.
  • Fix the intermittent spectator bug.
  • Change the network message handlers to delegate to methods rather than handle the messages themselves. 
    • Also, change the local clients to call those methods directly.
  • Remove network handling of objects that no longer need to be sent across the net.

Onward to 2012!

This year was awesome and I'm very excited about what the coming year will bring, both personally and professionally. I hope all of you have good things coming as well!

Wednesday, December 21, 2011

Testing the New Client/Server Arrangement

After the brief delay caused by my hard drive failure, the code is now in place for the local versions of the client and server.  The first round of testing has produced a pretty intimidating to-do list. Here's what went down:

The Procedure

I established a testing procedure that I believed would involve a sample of the affected functionality and uncover any regression issues. This is not a comprehensive test plan, but it did involve a good representative sample of client/server interaction.
  1. Select Single Player from the main menu.
  2. Log in as myself (Michael).
  3. Select a team color.
  4. Recruit a team captain.
  5. Send a chat message from the Lobby.
  6. Recruit another character.
  7. Upgrade a character.
  8. Signal ready.
  9. Move all characters through two or three rounds in the game.
  10. Cycle through the team and character info displays.

The Results

I went through those same steps four times in a row without modifying the code. The test results follow.

Step Test 1 Test 2 Test 3 Test 4
1 Passed Passed Passed Passed
2 Passed Passed Passed Passed
3 Passed Passed Failed (Server registered me as a spectator.) Passed
4 Passed Passed Unable to proceed. Passed
5 Failed (Engine defect.) Failed (Engine defect.) Failed (Engine defect.)
6 Passed Failed (Character list had disappeared.) Passed
7 Passed Unable to proceed. Passed
8 Passed Passed
9 Passed Failed (My characters worked but one AI got duplicated.)
10 Passed Passed


There is more work to be done!  I'm going to tackle one defect at a time and stick with these same ten steps until they work reliably.  Then I'm going to elaborate with a more detailed test plan.

Monday, December 19, 2011

Hard Drive Failure!

I hit a little bit of a snag in the project yesterday:  My hard drive began throwing errors and had to be replaced.

My first thought was that it was going to be an all-day project.  The first time I had to replace a hard drive (about 16 years ago), it took an entire weekend and two big economy-sized boxes of floppy disks.

But today, through the miracle of modern technology, it took only a few hours!  And that includes backing up the old drive, installing the new one, and restoring the disk image to it.  Super easy and with no problems whatsoever!  I now have 50% more drive capacity, 50% better seek times, a much faster (and more reliable) boot process, and no error messages complaining about error reports and failed writes.

Yay!  Now back to Team Laser Combat.

Friday, December 16, 2011

A Possible Alternative for the Server Upgrade

I had a thought today that I just want to capture here so I don't forget it.  Rather than give the server the complete overhaul that I described in my last blog post, I think I can get by with a better, simpler, more maintainable option.

In the current system, MHServerModule uses MHClientInfo's output stream to send messages to the client. Here's my new idea:

  1. Move the send() method from MHServerModule into MHClientInfo.  
  2. Extend MHClientInfo into MHLocalClientInfo and override the send() method to talk straight to MHLocalClient.
  3. When a client connects to MHServerModule, the method of connection will determine which version of the client info object is instantiated for that client.  If it's a network connection, it will associate an MHClientInfo with that user. Otherwise, it will use MHLocalClientInfo instead.
  4. MHServerModule will continue to run the listener thread automatically so the same server can be used for local or networked play without modification or subclassing.

I can't wait to see if this idea is as great as I think it is. Of course I'll continue to post my progress here.

Thursday, December 15, 2011

Moving on to the Server Side

OK, the client is working well in its new, more loosely-coupled form.  The only client-side component left to test is the new local client, which can't be properly done until it has a local server to talk to. That means it's time to turn my attention to the server side.

The best habit I've picked up lately is that I always begin a refactoring effort by analyzing and documenting the existing system first.  Here's the server's current form:

And here is a rough idea of what I have in mind for the imminent refactoring:

Check back in a few days to see how it's going.  :)

Friday, December 9, 2011

Client Upgrade in Progress

The refactoring of the engine's client package is working well so far.  I have managed to split apart the code that handles networking from the general client code without affecting the existing functionality of Team Laser Combat.  Here's the new class diagram.

Remaining tasks before the client upgrade is complete:
  • Rename MHClientModule to the more appropriate name MHNetworkClient as shown in the class diagram.
  • Refactor the server package to add compatibility for MHLocalClient.
    • Build a prototype to test both the networked and local versions of the client and server.
  • Test the new version of MHGUIChatClient that now depends on MHObservableClient to send notifications of chat messages.
  • Add logic to TLC to launch the correct client/server connection based on user role.
  • Move the net package into the io package (
    • Modify the deployment scripts to accommodate the new package hierarchy.

Monday, December 5, 2011

The New and Improved Package

Here's another class diagram of the package with several corrections and elaborations.

The heart of the new design is MHAbstractClient.  It will contain some useful constants along with basic implementations of common methods.

Derived from that is MHClientModule -- a class that already exists in an incohesive form. The new version will separate the low-level network communications into a new MHNetworkClient class, and will keep the stuff that's specific to a single client. There's no new functionality here; just a better division of labor.

Another subclass of MHAbstractClient is MHLocalClient.  I'm not sure if the engine itself will have this implementation, but I included it in the diagram anyway to demonstrate what I had in mind. The idea behind it is that situations where the game server is hosted on a player's machine should not require network communication, so a "dummy" class can take the calls and then just update the local data rather than send actual messages across the network...unless, of course, the update must be broadcast, but that can be handled on a case-by-case basis.

Finally, there's MHObservableClient.  This class will take an MHAbstractClient implementation as a parameter to its constructor.  This means that any subclass of MHAbstractClient can be made observable.  It maintains three different lists of listeners:

  • MHSystemMessageListener:  A listener for handling messages predefined by the engine.  These messages will be handled by the engine, but notifications can be sent to any class who subscribes to them.
  • MHChatMessageListener:  A listener specifically for chat messages.  May also be used to broadcast status messages from the server. The MHGUIChatClient component will implement this interface and provide a method for registering an MHObservableClient object
  • MHGameMessageListener:  A listener for handling game-specific messages.  These messages must be handled by the game code.
I haven't implemented this new design yet, but my goal is to have it in place and utilized by TLC by the end of the month.  Stay tuned to see if I can hit that target!