SyntaxHighlighter

Sunday 23 January 2011

Updating the Farseer Platformer tutorial to Farseer 3.2 (footnote)

Because I'm forgetful, and blogger doesn't like me editing blog posts with code in them, I've added a seperate post on updating the tutorial from Farseer 3.0 and 3.2.

There are only 2 issues you should encounter upgrading the 3.0 tutorial to 3.2. The first is that CollisionEventHandler has been renamed as OnCollisionEventHandler (but the only the name appears to have changed).

The second is that fixture.IgnoreCollisionWith() is now fixture.CollisionFilter.IgnoreCollisionWith(). And that's pretty much it! There are other changes between the two librarys, but these are the only ones we'd encounter.

If you need help updating the rest of the code from XNA 3.1 to 4.0, I suggest you check out the upgrade cheat sheet on xdsk2: http://www.nelxon.com/blog/xna-3-1-to-xna-4-0-cheatsheet/

Updating the Farseer Platformer tutorial to Farseer 3.2

***UPDATE***


This is an update of my previous post updating @roytries's Farseer Platformer tutorial on Sgt. Conker to Farseer 3.0. Since posting that item Farseer games have released Farseer Physics 3.2. This updated version will cover how to bring the original tutorial up to date to version 3.2, and I have added a secion at the end highlighting the changes from 3.0 to 3.2.


*************

Updating the Farseer Platformer tutorial to Farseer 3.2. 

The Farseer platformer tutorial on Sgt. Conker (here http://www.sgtconker.com/2010/09/article-xna-farseer-platform-physics-tutorial/) is a brilliant guide to getting started with Farseer and integrating it with your own drawing code rather than using the 'DebugView' that comes with the Farseer samples.

If you haven't already you should go and work through it, as it'll give you a good idea of what Farseer does and roughly how it works. Then when you're done, head back here and we'll go through how to get the tutorial working with Farseer 3.2.

Why bother? Can't I just use the version that the tutorial uses? 

Good question! I'll ask the second part of the question first. There is absolutely nothing stopping you using the older version of Farseer in your game, and indeed you may decide that it's preferable. The library for 2.1.3 compiles without error under XNA 4.0, and you may find it easier to work with because the units are simpler (see below).

So why would you bother to learn Farseer 3.2? Rather than trying to go over all the differences here, I'll direct you to the FAQ on the Farseer webpage:

http://farseerphysics.codeplex.com/wikipage?title=Differences%20between%20Farseer%20Physics%20Engine%202.x%20and%203.0&referringTitle=Tutorials

Its down to you to decide whether your project would benefit from the new features or not. 

On with the show!

If you're still reading then you're at least curious about updating the tutorial to Farseer 3.2. I'm going to start at the beginning of the tutorial and work my way through, highlighting the changes as I go. If you'd rather just look at the updated source code, then I've included the code files at the bottom of the page.

Set-up

First things first, head to the Farseer webpage and download the latest release. You can either just download the Farseer library, or you can download the version with samples included as this contains a helper class that we're going to be using in a moment. I've also included the helper class in the source below though, so just grabbing the library is enough.
Creating a project
This section should be largely unchanged. I've called my project FarseerPlatformer for consistency. The only thing to note is that you need to make sure you reference the correct FarseerXNA project (3.2 as opposed to 2.1.3).

My first physics

Here we start to see the differences in the new engine.

First of all we need to tweak the using statements that we add to Game1 slightly, as the namespaces in the library are different. Change them to:

using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using FarseerPhysics.Collision;

In 3.2, we no longer have a PhysicsSimulator. Instead we simply have a World class which we create an instance of. For our purposes we can treat this as a re-naming of the PhysicsSimulator class.

We create a new instance of World as follows:


world = new World(new Vector2(0, 20f));

Two things to note here. First, that the constructor for World is the same as the constructor for PhysicsSimulator, taking a vector2D representing gravity as its argument. Second, that the magnitude of the gravity vector is 20, rather than 500. This is due to a difference in the units that 3.2 uses, which we'll discuss in a moment.

Next up is updating our World each frame. This is done by adding the following to the bottom of the update method (before base.Update(gametime)):

world.Step((float)(gameTime.ElapsedGameTime.TotalMilliseconds * 0.001));

world.Step() is the new update method for the World class. Note that we use milliseconds * 0.001 rather than seconds. This gives us a more accurate timing, which will improve our simulation.

Now we look to creating physics objects. Under 2.1.3, you created a body which managed and reacted to forces on your object, and a geom or geometry which was used for collisions, friction etc.

Under 3.2 you still have these (although a geom is now a Shape) but they are tied together by a Fixture. In fact we can create our object in one go using FixtureFactory. Before we do that however, we need to talk about units.

In 2.1.3, Farseer worked with pixels as its units, so all calculations were done in screen space. Box2D (the physics engine that 3.2 is based on) uses a system called MKS, or Meters, Kilograms, Seconds.

So, if we just punch in the dimensions of the block from the tutorial, the engine tries to simulate a block 64m x 64m, falling about 400m down the screen. As well as that, the engine is optimized for objects with dimensions between 0.1 and 10m, so its unlikely to give us good results.

All of this means we'll need to convert our dimensions from pixels to a scale that works with the engine, and back again when its time to draw. Fear not, help is at hand!

In the Sample project entitled 'Farseer Physics Engine 3.2
SimpleSamples XNA' that you downloaded (or in the source code below) you will find a class called ConvertUnits (in the folder Samples/DemoBaseXNA). This is a helper class designed to solve exactly this problem. Copy this file into your project and change the namespace to FarseerPlatformer (or whatever you called your project).

Now we're ready to create our block. Replace your SetupPhysics method with the following:

protected virtual void SetUpPhysics(World world, Vector2 position, float width, float height, float mass)
{
       fixture = FixtureFactory.CreateRectangle(world, ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height), mass, ConvertUnits.ToSimUnits(position));
       body = fixture.Body;
       fixture.Body.BodyType = BodyType.Dynamic;
       fixture.Restitution = 0.3f;
       fixture.Friction = 0.5f;
}

As you can see, the parameters for FixtureFactory.CreateRectangle are pretty much an amalgamation of those for creating the Body and Geom objects in the tutorial, and replacing the PhysicsSimulator with our World instance.

The only parameter that possibly deserves special mention is the 4th, which is density.
3.2 calculates mass of your object based on its area and density. For this guide I have just substituted in the values that the original tutorial gave for mass, but you'll need to play with all of the values you use to get the effect you want.

We use ConvertToUnits.ToSimUnits() to convert our parameters to those suitable for use in the simulator. If you have a look inside the source code for this class you'll see that most of its methods are overloaded for doubles, ints, vector2D etc, so we really can just throw this method at our problem.

We also need to make some changes to the draw method. Replace PhysicsObject.draw() with the following method:

public virtual void Draw(SpriteBatch spriteBatch)
{
       spriteBatch.Draw(texture, new Rectangle((int)ConvertUnits.ToDisplayUnits(body.Position.X), (int)ConvertUnits.ToDisplayUnits(body.Position.Y), (int)width, (int)height), null, Color.White, body.Rotation, origin, SpriteEffects.None, 0f);
}

Notice that we have to convert all the values that we get from our simulated body back to pixel units, as otherwise we'd have a very, very small box!

You can check out the full source for the new PhysicsObject class below.

Now you just need to tweak the values inside your call to the PhysicsObject constructor like so:


box = new PhysicsObject(world, new Vector2(100, 0), 64, 64, 10, squareTex);

And we're done for this section. You box should be falling down the screen in all it's 3.2 glory.

Laying grounds

We actually don't need to change much in this section for the example to work, we just need to swap out the PhysicsSimulator parameter for a World parameter:

public class StaticPhysicsObject : PhysicsObject
{
    public StaticPhysicsObject(World world, Vector2 position, float width, float height, Texture2D texture)
        : base(world, position, width, height, 1, texture)
    {
        fixture.Body.BodyType = BodyType.Static;
    }
}

However, when you run your program, you may notice that there is a gap of a couple of pixels between the box and the ground when its at rest. I have two possible explanations for this, but I haven't been able to confirm either. The first is rounding errors when we convert our units, and the second is the fact that Farseer 3.2 adds a 1cm 'buffer' around objects in the simulation, to allow for Continuous Collision Detection (CCD), which is a new feature of the engine.

You can either live with this visual discrepancy, or tweak the spritebatch.draw() call in PhysicsObject to look like this:


spriteBatch.Draw(texture, new Rectangle((int)ConvertUnits.ToDisplayUnits(body.Position.X), (int)ConvertUnits.ToDisplayUnits(body.Position.Y), (int)width + 1, (int)height + 1), null, Color.White, body.Rotation, origin, SpriteEffects.None, 0f);

I've left the source code with the original that shows the gap, but you can do either.

Joints

RevoluteJoints seem to be much the same in 3.2 as they were in 2.1.3, so we only really need to tweak the CompositePhysicsObject class in a few places. Check out the class below:


public class CompositePhysicsObject
{
        protected PhysicsObject physObA, physObB;
        protected RevoluteJoint revJoint;

        public CompositePhysicsObject(World world, PhysicsObject physObA, PhysicsObject physObB, Vector2 relativeJointPosition)
        {
            this.physObA = physObA;
            this.physObB = physObB;
            revJoint = JointFactory.CreateRevoluteJoint(world, physObA.fixture.Body, physObB.fixture.Body, ConvertUnits.ToSimUnits(relativeJointPosition));
            physObA.fixture.CollisionFilter.IgnoreCollisionWith(physObB.fixture);
            physObB.fixture.CollisionFilter.IgnoreCollisionWith(physObA.fixture);
        }

        public virtual void Draw(SpriteBatch spriteBatch)
        {
            physObA.Draw(spriteBatch);
            physObB.Draw(spriteBatch);
        }

}

I won't painstakingly go through the changes as a quick look at the old and new classes side by side should highlight the differences.

However, one thing to note is that the last parameter in the call to JointFactory.CreateRevoluteJoint() is just relativeJointPosition, rather than physObA.Position + relativeJointPosition (I changed poA to physObA and poB to physObB).
This is because in 3.2 this method takes the position of the joint in the local coordinates of the first Body in the parameter list, rather than in world coordinates as in the old method.

Again keep an eye out for when to use pixels as your units, and when you need to use ConvertUnits to convert to meters.

Springs

Unfortunately AngleSpring isn't in 3.2. According to Farseer's creator it shouldn't be too much work to port the AngleSpring from 2.1.3 to 3.2, but I decided not to go down that route (if you decide to give it a go though, be sure to share your results with the community!).

Instead, I decided to 'fake' an AngleSpring with an AngleJoint with a TargetAngle of 0, and play around with it's Softness and BiasFactor properties until I found some values that seemed to work.

The result was similar the original, but not quite the same. If you come up with a better solution please do share it with the community!

Below is my faked SpringPhysicsObject, and the call to create it. The values are just those that I found to work, feel free to play around with them and see if you can get a better result.

public class SpringPhysicsObject : CompositePhysicsObject
{
        protected AngleJoint springJoint;

        public SpringPhysicsObject(World world, PhysicsObject physObA, PhysicsObject physObB, Vector2 relativeJointPosition, float springSoftness, float springBiasFactor)
            : base(world, physObA, physObB, relativeJointPosition)
        {
            springJoint = JointFactory.CreateAngleJoint(world, physObA.fixture.Body, physObB.fixture.Body);
            springJoint.TargetAngle = 0;
            springJoint.Softness = springSoftness;
            springJoint.BiasFactor = springBiasFactor;
        }
}

Force

Once again we don't need to change much here beyond the PhysicsSimulator/ World change. The only other thing to note is that the value for force used in the tutorial makes your box zip of the screen never to be seen again. Originally I played around with the value until I got one that felt ok.

As you no doubt saw from the original tutorial, impulses seem to work better for this sort of movement anyway, so that's what I've used here instead.


public class Character : PhysicsObject
{
        public float forcePower;
        protected KeyboardState keyState;
        protected KeyboardState oldState;


        public Character(World world, Vector2 position, float width, float height, float mass, Texture2D texture)
            : base(world, position, width, height, mass, texture)
        {
        }

        public virtual void Update(GameTime gameTime)
        {
            HandleInput(gameTime);
        }

        protected virtual void HandleInput(GameTime gameTime)
        {
            keyState = Keyboard.GetState();

            //Apply force in the arrow key direction
            Vector2 force = Vector2.Zero;
            if (keyState.IsKeyDown(Keys.Left))
            {
                force.X -= forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }
            if (keyState.IsKeyDown(Keys.Right))
            {
                force.X += forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }
            if (keyState.IsKeyDown(Keys.Up))
            {
                force.Y -= forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }
            if (keyState.IsKeyDown(Keys.Down))
            {
                force.Y += forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }

            body.ApplyLinearImpulse(force, body.Position);

            oldState = keyState;
        }
}

Most of the changes here are ones we have come across before, such as the use of Fixtures. However there are quite a few minor tweaks that need to be made, so I've included the whole of the source here in the text, as well as attaching the file below.

Other than again remembering to keep track of when you need to use pixels and when you need to use meters, the only other thing to note here is that body.LinearVelocity has to be replaced in its entirety. You can't change the X and Y components individually as you could in 2.1.3.


public class CompositeCharacter : Character
{
        public Fixture wheel;
        public FixedAngleJoint fixedAngleJoint;
        public RevoluteJoint motor;
        private float centerOffset;

        public Activity activity;
        protected Activity oldActivity;

        private Vector2 jumpForce;
        private float jumpDelayTime;

        private const float nextJumpDelayTime = 1f;
        private const float runSpeed = 8;
        private const float jumpImpulse = -500;

        public CompositeCharacter(World world, Vector2 position, float width, float height, float mass, Texture2D texture)
            : base(world, position, width, height, mass, texture)
        {
            if (width > height)
            {
                throw new Exception("Error width > height: can't make character because wheel would stick out of body");
            }

            activity = Activity.None;

            wheel.OnCollision += new OnCollisionEventHandler(OnCollision);
        }

        protected override void SetUpPhysics(World world, Vector2 position, float width, float height, float mass)
        {
            //Create a fixture with a body almost the size of the entire object
            //but with the bottom part cut off.
            float upperBodyHeight = height - (width / 2);

            fixture = FixtureFactory.CreateRectangle(world, (float)ConvertUnits.ToSimUnits(width), (float)ConvertUnits.ToSimUnits(upperBodyHeight), mass / 2);
            body = fixture.Body;
            fixture.Body.BodyType = BodyType.Dynamic;
            fixture.Restitution = 0.3f;
            fixture.Friction = 0.5f;
            //also shift it up a tiny bit to keey the new object's center correct
            body.Position = ConvertUnits.ToSimUnits(position - (Vector2.UnitY * (width / 4)));
            centerOffset = position.Y - (float)ConvertUnits.ToDisplayUnits(body.Position.Y); //remember the offset from the center for drawing

            //Now let's make sure our upperbody is always facing up.
            fixedAngleJoint = JointFactory.CreateFixedAngleJoint(world, body);

            //Create a wheel as wide as the whole object
            wheel = FixtureFactory.CreateCircle(world, (float)ConvertUnits.ToSimUnits(width / 2), mass / 2);
            //And position its center at the bottom of the upper body
            wheel.Body.Position = body.Position + ConvertUnits.ToSimUnits(Vector2.UnitY * (upperBodyHeight / 2));
            wheel.Body.BodyType = BodyType.Dynamic;
            wheel.Restitution = 0.3f;
            wheel.Friction = 0.5f;

            //These two bodies together are width wide and height high :)
            //So lets connect them together
            motor = JointFactory.CreateRevoluteJoint(world, body, wheel.Body, Vector2.Zero);
            motor.MotorEnabled = true;
            motor.MaxMotorTorque = 1000f; //set this higher for some more juice
            motor.MotorSpeed = 0;

            //Make sure the two fixtures don't collide with each other
            wheel.CollisionFilter.IgnoreCollisionWith(fixture);
            fixture.CollisionFilter.IgnoreCollisionWith(wheel);

            //Set the friction of the wheel to float.MaxValue for fast stopping/starting
            //or set it higher to make the character slip.
            wheel.Friction = float.MaxValue;
        }

        //Fired when we collide with another object. Use this to stop jumping
        //and resume normal movement
        public bool OnCollision(Fixture fix1, Fixture fix2, Contact contact)
        {
            //Check if we are both jumping this frame and last frame
            //so that we ignore the initial collision from jumping away from 
            //the ground
            if (activity == Activity.Jumping && oldActivity == Activity.Jumping)
            {
                activity = Activity.None;
            }
            return true;
        }

        protected override void HandleInput(GameTime gameTime)
        {
            oldActivity = activity;
            keyState = Keyboard.GetState();

            HandleJumping(keyState, oldState, gameTime);

            if (activity != Activity.Jumping)
            {
                HandleRunning(keyState, oldState, gameTime);
            }

            if (activity != Activity.Jumping && activity != Activity.Running)
            {
                HandleIdle(keyState, oldState, gameTime);
            }

            oldState = keyState;
        }

        private void HandleJumping(KeyboardState state, KeyboardState oldState, GameTime gameTime)
        {
            if (jumpDelayTime < 0)
            {
                jumpDelayTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
            }

            if (state.IsKeyUp(Keys.Space) && oldState.IsKeyDown(Keys.Space) && activity != Activity.Jumping)
            {
                if (jumpDelayTime >= 0)
                {
                    motor.MotorSpeed = 0;
                    jumpForce.Y = jumpImpulse;
                    body.ApplyLinearImpulse(jumpForce, body.Position);
                    jumpDelayTime = -nextJumpDelayTime;
                    activity = Activity.Jumping;
                }
            }

            if (activity == Activity.Jumping)
            {
                if (keyState.IsKeyDown(Keys.Right))
                {
                    if (body.LinearVelocity.X < 0)
                    {
                        body.LinearVelocity = new Vector2(-body.LinearVelocity.X * 2, body.LinearVelocity.Y);
                    }
                }
                else if (keyState.IsKeyDown(Keys.Left))
                {
                    if (body.LinearVelocity.X > 0)
                    {
                        body.LinearVelocity = new Vector2(-body.LinearVelocity.X * 2, body.LinearVelocity.Y);
                    }
                }
            }

            
        }

        private void HandleRunning(KeyboardState state, KeyboardState oldState, GameTime gameTime)
        {
            if (keyState.IsKeyDown(Keys.Right))
            {
                motor.MotorSpeed = runSpeed;
                activity = Activity.Running;
            }
            else if (keyState.IsKeyDown(Keys.Left))
            {
                motor.MotorSpeed = -runSpeed;
                activity = Activity.Running;
            }

            if (keyState.IsKeyUp(Keys.Left) && keyState.IsKeyUp(Keys.Right))
            {
                motor.MotorSpeed = 0;
                activity = Activity.None;
            }
        }

        private void HandleIdle(KeyboardState state, KeyboardState oldState, GameTime gameTime)
        {
            if (activity == Activity.None)
            {
                activity = Activity.Idle;
            }
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            //These first two draw calls draw the upper and lower body independently
            spriteBatch.Draw(texture, new Rectangle((int)ConvertUnits.ToDisplayUnits(body.Position.X), (int)ConvertUnits.ToDisplayUnits(body.Position.Y), (int)width, (int)(height - (width / 2))), null, Color.White, body.Rotation, origin, SpriteEffects.None, 0f);
            spriteBatch.Draw(texture, new Rectangle((int)ConvertUnits.ToDisplayUnits(wheel.Body.Position.X), (int)ConvertUnits.ToDisplayUnits(wheel.Body.Position.Y), (int)width, (int)width), null, Color.White, wheel.Body.Rotation, origin, SpriteEffects.None, 0f);

            //This last draw call shows how to draw these two bodies with one texture (drawn semi-transparent here so you can see the inner workings)            
            spriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)(Position.Y), (int)width, (int)height), null, new Color(1, 1, 1, 0.5f), body.Rotation, origin, SpriteEffects.None, 0f);
        }

        public override Vector2 Position
        {
            get
            {
                return (ConvertUnits.ToDisplayUnits(body.Position) + Vector2.UnitY * centerOffset);

            }
        }
}


Afterthoughts 

Well, hopefully this have given you enough to take what you learned in the original tutorial and carry it on into Farseer 3.2. As I said earlier, you will need to decide for yourself whether the potential confusion with using meters as opposed to pixels as the units for your physics simulation is worth it to benefit from the new features that 3.2 offers.

It may seem tricky, but as long as you keep track of which units you need to use where, its fairly easy to overcome.

Farseer simple platformer

So, a little a while ago I posted a tutorial on updating the Sgt. Conker Farseer Platformer tutorial by @roytries to Farseer 3.0. Hopefully later today I'll get a chance to repost that tutorial with an update for xna 4.0 and Farseer 3.2.

But first, I wanted to post a quick sample of how I did the character movement dynamics in Mario using Farseer (as requested by @chounard and a couple of others).

If you want to skip ahead to the sample, its linked to at the end of this post.

First thing to mention is the fact that its quite a different approach to the one used in @roytries tutorial. I orignally used the method from the tutorial almost verbatim, but ran into some issues. The main problem I had with the original method was caused by a combination of the composite nature of the character (a rectangle attached to a wheel) and the high friction used on the wheel.

The result of these two factors was that everytime the character ran into a wall it launched into the air as a result. I tried a number of different approaches to fix this, but nothing was quite right.

In the end I decided to switch my approach to something simpler. I chose to use a simple rectangle with a FixedAngleJoint to keep it upright. Obviously this removed the ability of the character to go up and down slopes, but that's not a problem in a Mario clone.

With the loss of the wheel, and therefore the use of a motor to create movement, I had to find an alternative method of locamotion. At first I attempted to use a force to create an acceleration, but although this provided a realistic motion, realism isn't really what I was going for in a Mario clone!

In the end I decided to modify the LinearVelocity property of the rectangle directly. Although this wasn't quite how Farseer was designed to be used, it didn't seem to break the simulation (apart from in one instance, which I'll come onto in a moment).

For jumping, I simply applied a LinearImpulse, much as I did in my upgrade to @roytries's tutorial.

For moving left/ right in the air, I limited the horizontal velocity in the air to that on takeoff. This isn't quite what @roytries did in his tutorial, but I found it gave a more Mario-like movement.

There was one last thing to add to the mechanics. As a result of manipulating LinearVelocity directly, anytime the character collided with the side of an object, it 'stuck' to it for as long as the player was still holding the thumbstick in that direction.

This was simple to overcome by simply setting the friction values of the platforms and walls to zero. Normally this might be an issue, with the character sliding straight off of the platforms, but as we are manipulating LinearVelocity directly we can simply set LinearVelocity.X to zero whenever we aren't airbourne and there is no left/right input from the thumbstick.

That's pretty much it. There are a couple of flaws, like the fact that when the character runs off the edge of a platform and falls they can still perform a jump, but I've left that in for the moment (just because I thought it worked quite well as a gameplay mechanic!) but it should be easy enough to remove by checking whether LinearVelocity.Y < 0 before calling Jump().

Below is the sample, not the prettiest code, but should give you the idea. If you haven't already, I suggest reading @roytries's tutorial: http://www.sgtconker.com/2010/09/article-xna-farseer-platform-physics-tutorial/ followed by my own update to that tutorial on this blog http://www.rabidlion.com/2010/11/updating-farseer-tutorial-to-farseer-30.html

Between them they should explain most of what is going on in the sample (including anomalies like having to add a pixel to the width and height of the rectangle being drawn to avoid a gaps between touching surfaces).

Hopefully I'll be able to fit in my update to my upgrade tutorial later today, but in the mean time, have fun with the sample!

http://simplefpplatformer.codeplex.com/

Tuesday 18 January 2011

Exciting times

I'll be honest, there were times when I thought this day would never come. I set out about 10-11 months ago to create 5 'learning games' whilst at the same time developing the basics of a 2D engine to base future projects on, including editors.

I originally planned that I'd need around 6 weeks to complete those games. Today, I have finished.

This announcement is tempered somewhat by the fact that I actually wrote this blog post last week, when I ACTUALLY finished. Unfortunately I just haven't had the time since to get the video below together.

Never the less, it is done, and Alta's embryonic phase if complete.  Still, the important thing, is that Mario, the final game, is done, and here is the video to prove it!


(Excuse the poor quality, and the bit at the end!).

As you can see, its not polished in the slightest, in fact in places its  downright sloppy. I make no appologies for that. I realised around xmas that somewhere along the line I'd lost sight of why I was making these games.

These games were meant to be the basis for my 'game driven development'  approach to Alta. And in my humble opinion, that process has been a success.

But wait, I hear you cry, how can you say it's been a success when its taken you months to put together a single level Mario clone? Well, to be honest, that's a good point. It has taken me far, far too long to accomplish what many could accomplish in a week.

The simple fact is, life has gotten in the way on a number of occassions, and that will always be the case. Nevertheless, I feel that the quality of the engine I have gotten out of this process has made it worth it, and will help me no end in the future both by making use of the engine itself, and from the experience that I've gained from it.

I still have a fairly hefty to-do list left for Alta, but that's the way it  should be, a good game engine should never be 'finished'.

And now to the future. First up is migrating to xna 4.0. The change to 4.0  happened during the development of Mario, and I took the decision not to  switch immediately. This has turned out to be a good call, as the difficulties in migrating between the two have now been extensively  documented, meaning its much easier for me to find information on the  upgrade process.

Also, having a finished demo allows me to ensure that Alta actually functions as intended post upgrade, rather than just making sure that it builds under 4.0, only to find much later that a particular feature was broken during the upgrade.

Migrating to 4.0 also means upgrading the version of Farseer that I'm using. Although Farseer 3.0 builds under 4.0 already, there are a number of fixes and optimisations in Farseer 3.2 that should be worth the upgrade. I'll also be doing an updated version of my Farseer Platformer upgrade tutorial for  3.2, probably this weekend, so keep an eye out for that. 

Once the migration is complete, I have some more work to do on the engine, in
preparation for my first commercial title. Things on the to-do list include an overhaul to the central gameState system. There are a number of bits of the system that are clunky and that I don't like, so fixing this is the first order of the day.

The second biggest change is to the Map editor. This editor needs to have line segments added to it to enable uneven terrain, it needs layers added to it, to enable parallax effects, it needs the ability to  search for tags in a map, and it desperately needs undo/redo implemented.
There are also a large number of other features that need adding, plus a lot of bugs that need squashing, but I won't list them all here.

I need to finish implementing an audio engine, as I didn't manage to finish it fully for Mario.

There are a large number of graphical features I'd like to add, including a particle system, including editor, for particle effects, and serveral  special effects in the rendering engine, such as dynamic lighting and bump mapping. The rendering system also needs optimising if its ever going to run on the xbox.

There is a sledgehammer option that I could use to crack all of these nuts in one go, and that is to migrate the rendering system to Sunburn. I have a pro license for sunburn 2.0, and its an amazing, ready optimised system, but it would mean learning a new API (even if only the 2D aspects for now)and I'm not sure that I can invest the time in that right now.

So what's all this in aid of? What's the point in upgrading the engine unless I'm planning to release a game. Well I am.

A few months ago I posted a teaser of a project that I was planning. The
image was below:



Today it gives me great pleasure to announce a new title from Rabid Lion Games, intended for entry into Dream Build Play 2011.

Ladies and Gentlemen, let me introduce, Sphero! (working title).

Sphero is a Metroidvania style platformer, with some interesting takes on classic game mechanics. You take the role of a Blip (a peaceful species of perfectly round beings) who, when his treetop village is attacked by the greedy industrialist Polygoni, sets out to rescue his fellow Blips who are being enslaved and forced to serve as machine components to make up for the Polygoni's inability to create anything round.

You must venture down from your treetop paradise, journey through treachous jungle, perilous mines, derelict cityscapes, and frozen wastelands. You must battle uncountable angular foes, the results of Polygoni's failed experiments to create artifical round beings for their machines. You must  find ancient Blip artefacts that will aid your journey, and allow you to defeat the soldiers and Lords of the Polygoni, and liberate your fellow Blips from their captivity. You must become the Sphero!

More information about Sphero will be released in future blog posts, but suffice to say, I'm very excited about this project. I've written a design document, which I intend to stick to, to try and nail down the scope of this game, and I'm already starting to make level and character designs on my
daily commute.

In terms of artwork, I may struggle with Sphero. The fact is, I'm not an artist, no matter how much I'd like to be. My attempt at a teaser and concept for box art (below) attest to that.



My plan is to create Sphero with the best programmer art I can muster, and keep trying to catch the attention of potential collaborating artists from within the community. Its almost  certainly too late to get an artist on board before DBP now, but if I can get something together that is fun to play and doesn't look too bad for DBP, hopefully I'll be able to attract an artist to the project on the back of
that.

Phew, well, that's quite enough for one post. I'll post soon with an update to the Farseer Platformer tutorial, and probably an update on the woes of migrating to xna 4.0.

Until next time Lion fans!