XNABS2: Pondering the Next Stage, Loader Code

Yesterday I finished cobbling together the first rudimentary bits of plumbing, clarifying some architectural issues that would make this version of the codebase a little easier to work with. There are a few interesting rabbit holes to explore along the way too, because .NET is a gigantic framework that encompasses all manner of programming tomfoolery.

Anyway, what’s in the current codebase is this:

  • A startup sequence that works within the confines of XNA’s notion of a Game Loop + Initialiation.
  • A pretty well-defined procedure for handling the creation of my own main game objects of various type and vintage within the context of the XNA Game Loop + Initialization.
  • A rudimentary Debugger and Console, though I haven’t rewritten the command stuff yet
  • An Input Manager
  • A Settings Manager
  • A package hierarchy
  • A Mercurial repository and central Bitbucket.org repository
  • A rudimentary event listener structure and inter-object communication setup for main game objects
  • Graphics Initialization and Debug messages written to the console

What was most important to me was to get the procedures, settings, and debugger setup so I could start building the rest and have some way to debug it. There are a lot of different things I could implement next, and I’d love to just dive write in and port the graphics routines. However, this routines are already written; what I should work on first is a new object creation language.

Currently, game engine 1.0 uses XML files to define everything that appears in the game at the Piece, Visual, and Player level. However, all this does is declare and name pieces and their associations visuals, along with players and their associated pieces. Also, the XML definition is a bit cumbersome, requiring multiple definitions to set up even a simple test. What I’d like for it to do is be a lot less redundant, and scale from very simple declarations of a handful of pieces in a space to complex hierarchies with behaviors attached to them. This GameXML language should be strive to minimally describe any game startup sequence. Each GameXML file also should serve as the defining datastructure for any level, presuming there are multiple levels in the game.

I’m thinking of something like this:

  • [piece name="uniquePieceName" [attributes]] is the way to declare any piece. This automatically adds the piece to a global piece dictionary if the name doesn’t exist, or updates its attributes if it already does. If the name attribute doesn’t exist, the piece is created with a unique name.

  • If the piece declaration occurs inside a [player] declaration, then the piece is created as described above AND it is added to the player’s piece array.

  • A piece can appear in multiple contexts like [player] and possibly other groups that are of interest to the game.

<

p>Pieces have the following attributes:

  • name = unique identifier of this piece
  • template = a piece name to copy attributes from

Initialization that may execute a script somewhere to complete the initialization as well as tagging the pieces with this role

  • type = type of piece, as defined in the game
  • visual = the type of visual to associate with this piece
  • role = logical role(s), comma separated
  • tag = logical tag(s), comma separated
  • behavior = an AI behavior
  • init = an initializing script to use to initialize any other parameters

3D world representations

  • position = vector3 coordinate of where this piece exists in space
  • scale = the size of the piece, defaults to unit 1 meter
  • direction = vector3 pointing
  • speed, maxspeed = how fast this can go up to maximum
  • turn, maxturn = how many degrees per second this object is allowed to turn

So, the next step would be to write the parser that reads this information and calls a myriad of functions and factories to set all this stuff up. Not the most fun, but it will make creation much easier. After that, we’ll port the visual classes to verify that it’s working correctly. Then, we can port the physics engine and AI behaviors. Then, we can write game logic for the referee classes.

AFTER SLEEPING ON IT

The very minimal piece would be to do the piece reading, and maybe read player and visual data structures. So let me start by porting the GameScreen.Prologue() routines XML reader, and see what I can do to encapsulate it.

Where to put this routine? GameScreen.Prologue() is executed as soon as the screen is created and pushed on the stack, which is handled in the LoadContent() part of the call. So that’s where I’m going to put it in the new architecture, except we don’t have a GameScreen to hold this data. So where does this live now?

For now, I think it makes sense to store this information in BaseGame somewhere. Creating a BaseGame Data.cs partial class and a Game.XML file. I also need to create a rudimentary piece class now.

PORTING

BaseGame Data has a new InitalizeDataStructures() and LoadDataStructures() methods that are called from the corresponding BaseGame.Initalize() and BaseGame.LoadContent() master entry points.

The piece-building logic is built around XmlReader, and there’s the option of having a validating reader that using an XmlSchema. I’m going to disable this for now. Related to this, though, is a class called StringUtility that converts the strings in the XML file. The current implementation uses default values in case the attribute being read doesn’t exist. This makes the code not only harder to read, but it also will mask problems with the game initialization XML file. I’m going to remove this feature.