Tuesday, November 29, 2011

Redesigning the Engine's Network Client

Perhaps a good place to start the refactoring process would be in the engine itself.  How's this look for a redesign of the mhframework.net.client package?


Corrections to be made to this diagram:
  • Declare sendMessage() in MHAbstractClient superclass.
  • Remove sendToAll() -- that's a server function.
  • Consider making MHLocalClient observable.  Or make an observable subclass of it.
  • MHObservableClient needs separate lists of observers for system messages vs. game messages.

More to come...

Monday, November 21, 2011

Rethinking Single-Player Mode

As I mentioned in my last rant -- I mean, "blog post" -- the game needs to be refactored before I go any further.  So I'm starting with the change that will do the most good:  removing all networking code from the single-player game mode.

What's the Problem?

Since the game was primarily intended to be a multiplayer game, the single-player mode has been treated almost like an afterthought.  Basically, it's just the multiplayer game configured to have just one human player.  Seemed like a good idea at the time.  Unfortunately, this means that I'm not only troubleshooting data issues and gameplay logic, but I'm also at the mercy of the underlying network even when the only client is on the same machine as the server.

What's the Plan?

The plan, therefore, is to remove all networking functionality from the single player mode.  The question is "how?"  Well, I've got an idea.

The current chain of responsibility goes like this:

  • TLCScreenBase is the base class from which all game screens are derived.  When a screen needs to update data, it calls out to TLCDataFacade.
  • TLCDataFacade is the single point of contact for all data updates and retrievals for the entire system.  If the data to be updated must also be shared with the server or other players, the data facade hands it off to TLCGameClient.
  • TLCGameClient is the intermediary between the local game instance and the network.  It takes responsibility for sending, receiving, and processing application-specific network messages, the actual transmission of which is handled at a slightly lower level by the engine's MHClientModule class.

My plan is to have TLCGameClient implement a version of the strategy pattern so that, upon instantiation, it will either create a true network client (as it's doing now) or it will create a simple object that "fakes" the network communication.  So in single-player mode (and perhaps even multiplayer hosting mode), the data will simply be communicated to the game server via method calls rather than being sent out on the network.  The server will implement a similar mechanism for communicating to local clients.

With this new system, the instantiation rule for each user role might be like this:

  • Single-Player:  Local client
  • AI Player:  Local client
  • Host LAN:  Local client
  • Join LAN:  Network client
  • Spectator:  Network client

What Could Go Wrong?

  • TLCDataFacade.  It currently contains a very complex mechanism for tracking individual data for multiple users.  This will not be necessary once the refactoring is complete, and should itself be refactored once the single player mode is separated from the networking functionality.  It should probably no longer be a singleton.
  • TLCGameServer. Since the local clients won't be using network communication to talk to the server, then the server should not use it to talk back to the clients.  A protocol must be established for the server to know how it should be communicating with each client type.  (My first thought on this:  Keep a list of network connected clients only, and then broadcast to them whenever a change is made.  Local clients will simply share the data with the server.)




Sunday, November 20, 2011

Candidates for Refactoring

It's official; Team Laser Combat is in serious need of a refactoring.  Because some elements of the original technical design were carelessly lost during implementation, the project has reached the a point where adding even simple pieces is becoming unnecessarily difficult.

The highest priority refactorings, as I see them, are these:
  1. There is no reason whatsoever to have single player mode use network messages to communicate between the client and server.  The proxy pattern prescribed in the original tech design would solve a number of current frailties and intermittent failures, as well as improve performance..
  2. The network modules really need to operate on a publish/subscribe model.  The observer pattern would greatly simplify the message handling code (which is a huge chunk of the system), eliminate some recurring errors, improve the functionality of the user interface, and go a long way to clean up the overall architecture of the client.
  3. I may do away with the authoritative, standalone game server.  Not sure about this yet.  I fear that the added simplicity of the game client would come at the cost of testability.

So much to do, so little time!