Sunday, 27 September 2009

Moving stuff over to new entity system

Yesterday I got the monster/projectile collision stuff moved over to the new entity system. I took the existing tests that me and Sam did and rejigged them. Pathfinding has also been taken over.

Unit testing each action was fairly easy, but doesn't give you much confidence that the entire interaction will work - pathfinding and shooting both involve a few different components talking to each other. To fully test this I've added some integration tests. They still run as fast as the unit tests, but they involve interactions between several classes (which should be a no-no in a unit test).

There are still a few tests that need to be added, or rather there are still things we need to work out. At the moment each action checks its user and target entities for certain components. If they exist it proceeds as normal. If it can't find them however, it just returns from its DoAction method. We'll need to think about cases where actions can act on entities that have a subset of the components they require to work fully, and what should happen when one or several can't be found.

Are both of you up for a chat later on this afternoon? Thinking about 1700 onwards...?

Sunday, 20 September 2009

Mocking Texture2D/SpriteBatch/Content

I've run into a problem.

For constructors for certain things, like the Monster factory, I'd like to add a list of Texture2Ds loaded at startup so that each factory method can give the entity the correct sprite.

However.

To mock a class (which has an implementation) rather than in interface (where the mock provides the entire implementation) you need to mock out everything that goes into its constructor. When you look at Texture2D or SpriteBatch, you'll see they take a GraphicsDevice which itself takes loads of stuff. The object graph explodes.

There does seem to be a way around this - someone's written a test framework called Scurvy.Test which purports to solve these kinds of problems by allowing you to instantiate the whole XNA thing during tests including the ContentManager, which would let us load Texture2Ds.

The other way I can think to deal with it is to abstract the graphics stuff away, dealing with some wrapper or other rather than relying on XNA's built in types.

Either way the unit tests aren't going to be as straightforward as I'd hoped.

Component-based entities II - The Wreckoning

I've made a start at implementing the system detailed in the last link. The diagram from the article sucks the boaby, so I've re-done it using YUML (a free, online UML editor - where you draw your UML using code!):

This says
  • Entity is composed of Form, Action and State
  • Form is composed of Space
  • Entity uses Space
  • Action uses State
Here's the code for the diagram if you want to edit it or fancy making your own:

[Entity]++-[Action]
[Entity]++-[State]
[Entity]++-[Form]
[Entity]uses-.->[Space]
[Form]++-[Space]
[Space]++-[Entity]
[Action]uses-.->[State]

Thursday, 17 September 2009

Component-based entities




(Sam, you were right - the blog is a good guilt-causing mechanism. I've not done any coding since before pyweek!)

At the moment I'm reading up on component-based entity systems. It seems like a much more flexible approach than the one we took initially. When you want to add some functionality it goes in as a standalone component, rather than being wedged into a possibly inappropriate place in the class hierarchy.

  • This is a good post from a dude that worked on the Tony Hawks games discussing his experience refactoring their whole engine to use component-based entities. Pretty light on code though :(
  • This other article discusses Dungeon Siege's system. They seem to have a mad hybrid going on. They have components, but they also have 'template' game objects which are like common archetypes. The components themselves seem to have some hierarchy going on: "The Attack component handles loading and launching ammo for projectile weapons. Requires the Common component. ".
  • This one has some actual code but it's pretty bare-bones. It does match the way I'm thinking about it though, which is that an Entity is nothing but a collection of Components.
  • Yet another one goes a slightly different route again. He's broken down all game objects into five classes - Entity, Space, Form, State and Action. Form is the visual representation and also holds State. Entities hold Actions (insantiated by game events). Space is stuff like view/world frustum, used for optimisation.
    Our components in this system become subclasses of Action and State. An Action operates on specific kinds of State objects (e.g. ItemPickup action interacts with Inventory state object). Here's an example from the article:
    • "Let’s say the car is a fast car and we want to make it go even faster. However, what we do not want to do is make the car faster. If we were to make the car faster, we could only affect the behavior of that car. Instead, we make the "fast" faster, and therefore ANY game token car that can go "fast" can be affected if we so choose. Much more importantly, not only could any token representing a car be affected, also, ANY game token with a "fast" behavior could potentially be modified regardless of what it is meant to represent."

I'm going to have a go at implementing the last one, starting with something pretty simple so we can get back to having monsters and bullets collide as quickly as possible. As always, let's hear your thoughts :)

Sunday, 6 September 2009

Pyweek's finished!

And here's our game

It came out pretty well for a week's effort, especially considering that the vast bulk of the content was added on Saturday (and the wee hours of Friday night).

Anyway, this means I'll be back on the project now - although maybe not today. Got a lot of missed housework to catch up on :( (and I need a break :P)

Thursday, 3 September 2009

UI update

The UI layout is working really nicely and the input catching and state selection is done- it just needs to fire events, but I have yet to read about the Event model in C#. I'm figuring each button will fire an ID from an event enumerator somewhere, and this ID gets passed into its constructor. Then the UI is finished- any object that is interested should be able to subscribe to that ID.

So at the moment it is looking good, you can mouseOver or click something and it will change state and the entire set of components will be re-layed out to fit around the new state. Some of the design decisions are a compromise, I did manage to get a tidier, better encapsulated structure with less transparency in earlier revisions but the code was fucking mental and order-of-operation dependent. I'm happy with this version, the only problems being that it exposes the state (previously internalised) and also exposes some redundant properties. I spent a long time trying to find a perfect solution for this but it is way beyond the scope of this game.

What remains to be done in the UI is animation- specifically tweening between states. This should be very easy to implement and means any menu should be able to intrinsically animate its state changes with zero additional code- a cool side effect of the design. I'll probably mess about with this over the next couple of days while Gary is busy with pyweek.

In other news, I am going to be splitting my time between this project and an iPhone game project with Al- looking to make some cash from the AppStore gold-rush. Don't have a mac yet but we will be writing the game engine under windows with C++ / OpenGL-ES and doing the minimal porting required to get it running on a phone later on. It's a big job- I made a solo attempt a few months back and got as far as loading PNG files into textures. The foundational work required is pretty hefty but the potential rewards are great, and I don't see the iPhone going anywhere for a while.