Friday, March 29, 2013

Server Work

I haven't posted much in the last week or two.  I have been making progress, but largely I've been integrating the game client and simulation engine with the server system I'd written last year.  So, nothing glamorous, just a lot of 'oops!, I shouldn't have done it that way' sort of restructuring going on.

There are som interesting bits.  The simulation engine references XNA in order to use the various types (vectors, matrices, quaternions, etc,) as well as being able to load models.  Per triangle hit detection is one of the requirements, so I definitely have to have the model data and account for animation movement on the server.  So I figured I'd just reference and use XNA there, though definitely not actually running via the Game class of course.

I quickly realized that there was a serious problem.  Loading a model with XNA not only loads the data in the model file, it loads the textures and puts the model's vertices and indices in VertexBuffers and IndexBuffers as well.  Texture2Ds, VertexBuffers and IndexBuffers live on the video card.  There's definitely no guarantee that whatever machine the server is running on would have a DX9 video card; likely they'll be virtual anyway.  Plus it's just a waste.

Unfortunately there's no way to modify that loading behavior.  I considered looking up the format of the XNB files (the binary format XNA compiles resources to) and reading them directly, but then I realized that MonoGame does that already.  MonoGame is an open-source implementation of XNA.  It isn't entirely complete yet, so I can't use it on the front end, but for the server it should be entirely enough.

Even better, since it is open source, I was able to go into the ContentManager class and add some hacky code that allows to you instantiate a ContentManager and load a model without loading any shared resources (i.e. those that would reside on the video card).  Exactly what I needed!

There were some sticky problems with integrating this, however.  Since the SimulationEngine project was referenced from both the client and server, and both XNA and Monogame reside in the Microsoft.XNA.Framework namespace.... yeah, it really blew up at first.

Initially I wrote some interface code that did a bunch of casting and conversion between the two, but that was just ugly.  In the end I refactored the base SimulationEngine, making two additional projects, SimulationEngineClient and SimulationEngineServer.  Both these projects actually link to the files in SiimulationEngine, making them exact duplicates (though each overrides a few files).  Then SimulationEngineClient links to XNA, SimulationEngineServer links to Monogame.  Since they reside in the same namespace, nothing need change.  Boom, problem solved.

Anyway, each of these is inherited by RogueMoonSimulationEngineClient and RogueMoonSimulationEngineServer, which implement Rogue Moon game specific logic.

It is a bit twisty, but the code is pretty clean, and so far it hasn't presented too many problems, now that I have this all worked out.  It took me a while to get here, though!


Sunday, March 17, 2013

I Find Git Very Annoying

So I've generally been working with Bitbucket and Mercurial.  Everything has been happy and working well.

But lately I've done some experimental work with Azure, and also decided to clone Monogame from GitHub.  I'm taking Monogame and making some additions so that you can load XNA Models server side.  The changes will allow you to load a model without the textures, vertex/index buffers and effects.  Which also means you don't need a graphics device.  This will let me load the model and bones server side (which is likely headless) for per-triangle hit accuracy even with animation.

Anyway, so I clone Monogame to Bitbucket.  Fine.  I then clone the repository locally.  I tried making may changes and pushing, but got an error.  Essentially the remote repository was ahead of my local (which I had JUST pulled).  Eeeeeh?

Well, it seems like what is happening is that when I clone the repository it is taking from the Develop branch.. but when I try to push it is pushing to the Master.

You'd think that would be easy to change, but no... it's probably somewhere in some arcane command line option that I'll have to dig to find.

Anyway, it doesn't just work like Mercurial has been doing.  I'm sure I can dig to make it work... but this is my first encounter with Git, and it has thusfar failed completely to do something VERY EASY.

I didn't know anything about Git previously, but I think I'll avoid it from now on if practical.  Pull->Change one line->Commit->Push ought to just work.

Edit:  I wasn't able to figure out how to do this from the command line or Git GUI.  But GitHub for Windows allowed me to easily switch the operating branch.  Twenty seconds there and I was done.  Thanks, Git.