Laying the foundation...

After setting up the development framework (Visual Studio 2005 and XNA Game Studio 2.0) and twiddling with the code for the whole day I'm getting something rendered on the back buffer.  :)
I'll start describing the main architecture I built (very roughly).

Remember that I actually just started building the game and I'm not completely sure whether the architecture will work out well or if I'll have to rewrite everything from scratch tomorrow. Anyway, let's get started!

Game entities: Actors

By reading some documentation of open source game engines (like Ogre3D) I know that you have to define your "entities" somewhere in the engine. Those entities will be our logical game unit: everything displayed on screen (or not) that plays a role in the game should be aggregated into an own object, with its own logic. I'll call these entity classes "Actors" and will define a couple of interfaces for using them (this is the first class hierarchy I tought of, but it will most likely change in the future).

File tree IActor interface:

interface IActor { Vector3 Position { set; get; } Vector3 Direction { set; get; } Vector3 Up { set; get; } Vector3 Right { set; get; } float Scale { get; set; } void Update(GameTime gameTime); Matrix World { get; } }

This is the base interface which every Actor will provide: it exposes everything needed to position the actor in the world (it returns a World transform matrix).

IPhysical:

interface IPhysical : IActor { Vector3 Velocity { get; set; } Vector3 Acceleration { get; set; } float Mass { get; set; } ICollisionDetector CollisionDetector { get; } bool IsStatic { get; } void ApplyForce(Vector3 force); }

This interface extends the IActor interface and provides several additional parameters, like velocity, acceleration and mass (which will be very useful for implementing classes like the player's ship or the planets). I also defined an provisory ICollisionDetector interface, where to plug in whatever collision handler I'll come up later on.

IControllable:

interface IControllable { void AccelerateSideways(float amount); void AccelerateFrontally(float amount); }

This very simple interface takes an acceleration amount (range [-1, 1], which is the same range of XNA's gamestick input) and will eventually enable the user to control the actor using one of the input handlers of the game (see below).

IRenderable:

interface IRenderable { void Render(GameState gameState, ICamera camera); }

Well... Classes that implement this interface will be able to render themselves on the screen.  :) I couldn't think of any actor not implementing this interface at the moment, but just in case, it should be possible for an anctor to exist and not be shown to the user.

After these interfaces, I defined a couple of base classes that provide basic functionality to deriving classes:

  • BaseRenderable: abstract class that (abstractly) implements IRenderable and provides several rendering helper methods.
  • BaseDynamicModel: an actor which owns a Model, renders it if necessary and implements the IPhysical interface (and therefore has position, rotation, velocity and acceleration vectors).
  • BaseScenery: a simple actor that implements IActor and can be rendered. It cannot be moved.

And finally, the final classes that will be instantiated by the game!

  • PlayerShip: the main model, implements IControllable and has a lot of code that handles rotation and movement. It also starts vibrating when traveling at high speed.
  • Planet: base class of every planet, loads a simple Sphere model and renders it in an absolute (and static) position. Will have to change it soon.
  • SkyDome: derives from BaseScenery and represents the far away spherical dome with a nice galactic texture. Not yet complete.

And that's it.

View and Projection: the Cameras!

All classes implementing IActor compute and provide their own World transform matrix to the renderer. The rendering process also need the View and Projection matrices: it's the camera's duty to provide them.

As usual, I defined a very basic interface (ICamera) with a couple or properties (Position, TargetPosition... View and Projection) and then derived several usable classes. At the moment that is:

  • SimpleCamera: a simple camera targetting a position in the world. A bit like the Unreal Tournament spectator camera.
  • ChaseCamera: a camera that will always follow a certain point of the world, facing a certain direction (with a given offset).
  • ChaseSpringCamera: this one derives directly from the camera above and additionally has a velocity vector and some physical properties that make it move gracefully and elastically through the world, while always following its target. Honestly most of the code comes from the XNA samples.

I'll create an ArcBallCamera in the future if I have the time.

The InputHandlers

This component of the game is of paramount importance and should work really well, while providing sufficient abstraction to map gamepads and keyboard to the same commands (XNA already provides a wonderful input interface!). I decided to keep it simple, as the rest of the demo at the moment, starting with an interface:

interface IInputHandler { void Update(GameTime gameTime); void RegisterActor(IControllable actor); void DeregisterActor(IControllable actor); }

As you can see, each handler will be updated in the Update loop of the game and will keep an internal list of actors (implementing IControllable). These actors will be notified of the user's input (which will be correctly translated into frontal or sideward acceleration).

What we got 'til now

Demo screenshot

Ok, that's not really astounding, but it's something at least (and it should be enough since I've never used XNA before yesterday  :))!

The ship whizzes around very nicely, and starts vibrating when traveling very fast (note: if you press [Space] the ship accelerates 4 times quicker than usual, looks really funny). The black circular blurb on the right is a planet (textureless). Nothing funky, but I'll keep you updated in the following days and we'll see what will come out of it!