Category: XNA

Whatever happened to SBARG?

Posted by – August 17, 2010

“What ever happened to EssBarg?”

“Did you ever finish SBARGE?”

“What was that game called you wrote?”

I get asked questions all the time about SBARG and it’s quite humbling to know

1) people still remember it

2) People still want to see it released.

SBARG was a game I wrote which never quite made it to release quality. This seems like a lifetime ago now, but some recent activity inside a code window has inspired me to start thinking about SBARG once again. It’s been a long time since I thought SBARG in a code context and thought it would be good for my motivation to write something about it.

SBARG went through a couple of major overhauls, the first one was following our submission to calling all games.

screenshot2

After we got some feedback from this, we decided we needed to make the gameplay much more interesting and to make major changes to the HUD and some subtle changes to the art style.

So off we went on quite an epic code change to the A.I and the general gameplay engine. As we did this we also introduced much more artwork and lots of polish to the visual effects in the game. It was looking great and we felt we were getting close.

We reached a point where we thought we were at “BETA” quality and we ran it past some friends and family to try out. We also pushed this version for XBLIG Playtest. Thanks to the ruthless testing of some of the people we realised we had some issues. The major one was people liked playing it, but it was frustratingly slow when the game started to turn on you. This was a major flaw in my naive attempt at an A.I engine. There were a lot of other cosmetic issues but these were minor in comparison to the big flaw.

From here, we pretty much went back to the drawing board with the A.I. Artistic changes were put on hold and I began writing a fresh new A.I library, and decided to actually think about it before implementing.

This turned out amazingly well in my opinion, and BRAINS was born.

It took much less work than I feared to implement the BRAINS functionality into the old SBARG game code. All my existing game engine and scenario engine continued to work. The result was all our previous level designs worked, and they ran at a suitable frame rate.

So at this point we wondered how far we could push the new engine and what doors it may open up for gameplay. The results were astounding, we managed to have levels with many more A.I enemies than we had originally planned way back when we first jotted down the idea for an RTS game. We were thrilled.

We decided that we should try to make the most of the new awesome A.I engine and redesign some of the levels. We added much more complex scenarios and many more enemies. This caused issues with balancing and so the test/tweak/test cycle began.

This took many a late night to get it to a point where it was actually playable again. Once we were happy we hadn’t made it too easy and that there were no major outstanding bugs we decided to run it past our family & friends again.

The response was great and I think everyone enjoyed it. Some people found it too hard while others wanted it to be more challenging. Some wanted more game modes, others wanted difficulty settings. All in all people seemed to think we had a half decent game on our hands. (relative of course, it’s not like we had just written SBARGCraft II)

The only thing left to do was nail down the story elements and finalize some art work. It was then ready to publish on XBLIG and see if anyone out in the real world actually liked it.

So what happened?

Well, I managed to pull my finger out and find myself an awesome real job before the previous one killed me off (literally)

Since then I’ve been so busy with work and spending all my free time with my family to make up for not doing as much in the previous 18 months.

Unfortunately SBARG never got released due to real life :(

So that’s it. That’s what happened to SBARG!

Wondering what’s next for SBARG? Me too!!! Stay tuned!

A new direction

Posted by – October 30, 2009

It’s been a crazy few months. Working extremely hard on many different projects, some commercial, some for personal gain and some which are for you… the Community.

I’ve decided to keep my www.conkerjo.com blog but slightly change the direction of it to be more personal. So where will the technical articles and blog posts go? well, we’ve setup a new website called Sgt. Conker and you can see it here www.sgtconker.com
This site will host game development related articles among other things such as my open source projects and other projects and ideas which come from the other people involved.

I’d like to say a special thank you to Björn's and Catalin Zima for offering tons of support and help with the new web site. The are both part of the new council formed which currently has 6 members to help out with moderating the website and providing hot new news and infor for your pleasure.

Please welcome us by getting involved, post in the forum, submit articles, offer suggestions, ideas, critism. It’s all welcome.

Here’s hoping I won’t be so busy after mid november and I can blog more about some of the things I’ve been up to.

Zune HD Accelerometer Basics

Posted by – October 2, 2009

I was just messing around with my Zune HD while taking a short break from my main project when I thought I could port my TinyEngine to it in no time.

Sure enough, it took about 12 seconds.

In my dummy project I have Mr Tiny just smiling away in the center of the screen.

mrtiny

I wanted to get him to move around by just using the accelerometer. This was really simple.

I just call Accelerometer.GetState(); which returns a AccelerometerState. The AccelerometerState contains a Acceleration of type Vector3 which contains the direction of the accelerometer. I then just pass the direction of tilt to my engines Sprite Move command, as a Vector2.

Something like this

Vector2 accel = new Vector2(state.Acceleration.X, -state.Acceleration.Y);
    AccelerometerState state = Accelerometer.GetState();
    Vector2 accel = new Vector2(state.Acceleration.X, -state.Acceleration.Y);
    this.mrTiny.Move(accel * 100 * elapsed);

Clamp it to the screen

    this.mrTiny.PositionX = MathHelper.Clamp(this.mrTiny.PositionX, this.ScreenBounds.Left, this.ScreenBounds.Right);
    this.mrTiny.PositionY = MathHelper.Clamp(this.mrTiny.PositionY, this.ScreenBounds.Top, this.ScreenBounds.Bottom);

 

And there we have it, you can tilt your Zune HD to move around Mr Tiny.

Short but sweet uh?

The code is linked just below. I’ll be looking to do more Zune HD samples in the near future, as well as adding gesture support to TinyEngine.

Once I’m finished with my secret project.

Source Code (Includes Tiny Engine Source)

Redirecting the console output in c#

Posted by – September 17, 2009

Often when writing code in an agile way, the best way. We might write something like this.

 Console.WriteLine("I'm super awesome"); 

I don’t think it’s the correct way to do logging in your game or application. But such is life, stuff happens and we’re tasked with resolving it.

We need to get all these logging messages into some readable form inside my game, or app. This needs to be done by the time you wake up yesterday.

So how do we replace potentially hundreds and hundreds of Console.WriteLine’s?

Don’t panic, I have a solution. We can redirect the Console output to anything we want. All we need is an IO Stream and we can do whatever we like with it.

I decided to do this and output it to a label which scrolls in my application. It’s not the most ideal solution for viewing it either, but we went from not knowing W.T.F was going on, to seeing snippets of info fly by. It allowed us to progress with the next problem. This was a minor change and isn’t required to be in the final product so it doesn’t have to be “pretty” per say.

Here’s how I did it. I inherit from the class TextWriter and override the WriteLine method. I just happen to know all my logging calls are coming into WriteLine. Your situation may require more methods to override.

I expose an event which fires every time WriteLine is called and my app picks this up and displays it on screen. Here’s the full class

 public class TextBoxWriter : TextWriter
{
    public event Action<string> OnConsoleWriteLine;

    public override void Write(string message)
    {
        this.OnConsoleWriteLine(message);
    }

    public override Encoding Encoding { get { return Encoding.UTF8; } }

    public override void WriteLine(string message)
    {
        Write(string.Format("{0}\n", message));
    }
 } 

Once we have this class we simply have to redirect the console out put by using the Console.SetOut command.

 writer = new TextBoxWriter();
writer.OnConsoleWriteLine += new Action<string>(writer_WriteHappened);
Console.SetOut(writer); Console.SetOut(writer); 

Simple, yet effective. I should get back to work :)

K.I.S.S – C# Properties

Posted by – September 10, 2009

Keeping up with the K.I.S.S principle my previous post prompted an interesting debate in the #xna IRC channel.

Somebody commented

“User> Also, "public Vector2 Position { get; set; }" will transmit some bad habits to noobs. :]”

&

“<User> It expands it into a function call. If the get and set is public, it may as well be a public field.”

I missed most of the debate but here’s my take on things.

Why should we use auto properties as opposed to being maticulous and writing out the private variable? Or why bother with a property at all if you can’t be bothered to write the private variable and set and return it?

Firstly, I don’t see how it produces a bad habit. I come from a background where having to write a private accessor every time I needed a property was a very tedious task. Especially when dealing with hundreds of classes at the start of a large project, so this was a very welcome addition to .net for me as writing a private accessor just to return it and set it felt like a waste and left me with a ton of private variables I didn’t really need.

A few arguments for using them are.

  • It follows the K.I.S.S principle.
  • It looks a lot cleaner and has a smaller code footprint than writing a private property too.
  • They’re so easy to implement using the Visual Studio Snippet feature. prop <tab> type <tab> name <enter>
  • It allows you to maintain the API while giving you room for flexibility in the future to change the functionality of the get/set.
  • If a third party relied on using reflection for API, fields are treat differently to properties.

 

So what really happens when we do use these auto properties.

Not surprisingly it does something very similar to what you would do if you write the private accessor yourself. Here’s an example.

Here is my own property with my own private variable. This took blood sweat and tears.

private int myvalue;

public int MyValue
    {
        get { return myValue; }
        set { myValue = value; }
    }

 

Here is my auto property for the lazy people.

 

public int MyValue { get; set; };

And here is what your code looks like after you compile an auto property.

[CompilerGenerated]
private int &lt;myproperty&gt;k__BackingField;

public int MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.&lt;myproperty&gt;k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.&lt;myproperty&gt;k__BackingField = value;
    }
}

 

It’s just doing the same thing, except adding an attribute to say it was generated by the compiler.

Over the course of a large application or a game, you would be amazed at how much time this saves, it keeps it simple and allows you to tighten up property get/set methods later in the development cycle.

There are a lot of other differences between Fields and Properties in c# but the main ones which effect this discussion are listed above.

Thanks to Björn for giving me the nudge to post.

This post is sponsered by Björn’s XNA Adventures

K.I.S.S – Fading between images with XNA

Posted by – September 6, 2009

In my first Keep It Simple Stupid (K.I.S.S) post I wanted to write about fading between 2 images.

Fading between 2 images is a very simple task using XNA, yet I’ve seen some severely over engineered solutions in the past. Here’s my take on the problem.

We need to fade from one image which is currently displaying on screen to another image we have stored in memory.

Here are 3 states of 2 images fading between each other.

The Start

blogimage1

The Fade

blogimage2

The Result

blogimage3

To keep it simple we use functionality within the XNA framework so we don’t have to write our own. This can be done using the SpriteBatch AlphaBlend which just happens to be the default option when calling Begin on a SpriteBatch.

Simply call Begin, draw the image currently on screen at a reduced alpha, then draw the image you want to transition to over the top with a alpha set to the other extreme.

I created a class which takes care of the drawing and alpha transitioning. Once we create an instance of the CustomImage class we must call Update, passing it the elapsed time since the last frame and also call the Draw method to draw the transition.

If there is no transition the CustomImage will simply draw the Image set at full opacity.

We define the amount of time to take in a transition in the constructor of the CustomImage or it can be changed via the TransitionTime property.

To start a transition just pass a Texture2D to the TransitionTo method. This will begin the process of fading between the two images and will completely switch over to the new image once complete.

Here is the full class implementation.

 public class CustomImage
{
    private float timer;
    public CustomImage(Texture2D initialImage, Vector2 position, Vector2 origin, float transitionTime)
    {
        this.Image = initialImage;
        this.TransitionTime = transitionTime;
        this.Color = Color.White;
        this.Rotation = 0;
        this.Position = position;
        this.Origin = origin;
    }

    public float TransitionTime { get; set; }

    public Texture2D Image { get; private set; }

    public Texture2D ToImage { get; private set; }

    public Vector2 Origin { get; set; }

    public Vector2 Position { get; set; }

    public Color Color { get; set; }

    public float Rotation { get; set; }

    public void TransitionTo(Texture2D image)
    {
        if (this.ToImage != null)
        {
            return;
        }
        this.ToImage = image;
        this.timer = 0;
    }

    public void Draw(SpriteBatch batch)
    {
        if (this.ToImage == null)
        {
            batch.Draw( this.Image, this.Position, null, this.Color, this.Rotation, this.Origin, 1f, SpriteEffects.None, 0);
        }
        else
        {
            int alpha = (int)((this.timer / this.TransitionTime) * 255);
            this.DrawImage(batch, this.Image, 255 - alpha);
            this.DrawImage(batch, this.ToImage, alpha);
        }
    }

    public void Update(float elapsed)
    {
        // We must be transitioning
        if (this.ToImage != null)
        {
            this.timer += elapsed;
            if (this.timer &amp;amp;amp;gt;= this.TransitionTime)
            {
                this.Image = this.ToImage;
                this.ToImage = null;
            }
        }
    }

    private void DrawImage(SpriteBatch batch, Texture2D texture, int alpha)
    {
        batch.Draw( texture, this.Position, null, new Color(this.Color, (byte)alpha), this.Rotation, this.Origin, 1f, SpriteEffects.None, 0);
    }
} 

&nbsp

To use this class we pass a Texture2D, a position, an origin and a length of time we want a transition to take.

Calling Draw will draw the image set until you pass a Texture2D to the TransitionTo method.

Here’s is the full Game code to show how I used this class in the sample which you can download at the end of the page.

 public class Game1 : Microsoft.Xna.Framework.Game
{
    private GraphicsDeviceManager graphics;
    private SpriteBatch spriteBatch;
    private SpriteFont font;
    private CustomImage image1;
    private CustomImage image2;
    private float storedTimer = 2;
    private KeyboardState currentKeyboardState, lastKeyboardState;
    private Vector2 imageSize = new Vector2(400, 300);

    public Game1()
    {
        this.graphics = new GraphicsDeviceManager(this);
        this.Content.RootDirectory = &quot;Content&quot;;
    }

    private Vector2 ScreenSize
    {
        get
        {
            return new Vector2(this.GraphicsDevice.Viewport.Width, this.GraphicsDevice.Viewport.Height);
        }
    }

    protected override void Initialize()
    {
        base.Initialize();
    }

	protected override void LoadContent()
    {
        this.spriteBatch = new SpriteBatch(GraphicsDevice);
        this.font = this.Content.Load&lt;spritefont&gt;(&quot;Fonts/Arial&quot;);

		Vector2 position = new Vector2((this.ScreenSize.X / 4), this.ScreenSize.Y / 2);
        this.image1 = new CustomImage(this.Content.Load&amp;lt;texture2d&amp;gt;(&quot;Textures/Image1&quot;), position, this.imageSize / 2, this.storedTimer);

		position.X += this.ScreenSize.X / 2;
        this.image2 = new CustomImage(this.Content.Load&amp;lt;texture2d&amp;gt;(&quot;Textures/Image2&quot;), position, this.imageSize / 2, this.storedTimer);
    }

	protected override void UnloadContent()
    {
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        {
            this.Exit();
        }

		this.lastKeyboardState = this.currentKeyboardState;
        this.currentKeyboardState = Keyboard.GetState();

		float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

		this.HandleInput();

		this.image1.Update(elapsed);
        this.image2.Update(elapsed);

		base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        this.GraphicsDevice.Clear(Color.Black);

		this.spriteBatch.Begin();

		StringBuilder instructions = new StringBuilder();
        instructions.Append(&quot;Space : Transition&quot;);
        instructions.Append(Environment.NewLine);
        instructions.Append(&quot;PgUp / PgDwn : Increase / Decrease Timer&quot;);
        instructions.Append(Environment.NewLine);
        instructions.Append(string.Format(&quot;Transition Time : {0}&quot;, this.storedTimer));

		this.spriteBatch.DrawString(this.font, instructions, new Vector2(25), Color.White);

		this.image1.Draw(this.spriteBatch);
        this.image2.Draw(this.spriteBatch);

		this.spriteBatch.End();

		base.Draw(gameTime);
    }

    private void HandleInput()
    {
        if (this.IsNewKeyPress(Keys.Space))
        {
            this.image1.TransitionTo(this.image2.Image);
            this.image2.TransitionTo(this.image1.Image);
        }

        if (this.IsNewKeyPress(Keys.PageDown))
        {
            this.storedTimer -= 0.25f;
            this.image1.TransitionTime = this.image2.TransitionTime = this.storedTimer;
        }

		if (this.IsNewKeyPress(Keys.PageUp))
        {
            this.storedTimer += 0.25f;
            this.image1.TransitionTime = this.image2.TransitionTime = this.storedTimer;
        }
    }

    private bool IsNewKeyPress(Keys keys)
    {
        return this.currentKeyboardState.IsKeyUp(keys) &amp;amp;amp;amp;&amp;amp;amp;amp; this.lastKeyboardState.IsKeyDown(keys);
    }

    private void DrawImage(Texture2D image, Vector2 position)
    {
        this.spriteBatch.Draw(image, position, null, Color.White, 0, this.imageSize / 2, 1, SpriteEffects.None, 0);
    }
} 

 

You can download the sample project with complete working sample here

The Week in Code by Björn

Posted by – July 14, 2009

Björn (or boki) has written his 7th instalment of The Week in Code. Hit the RSS button and maybe he’ll feel obliged to keep it up and add some more. I’m in there 2 weeks on the trot by the way :D

Björn’s XNA Adventures

BRAINS – XNA A.I Library – Source Code

Posted by – July 12, 2009

image As mentioned in a previous post I have been working on an A.I library for use with XNA games. I have attached the latest source code to this post as well as the location to the SVN which I will be continuing to update.

If you do try it out and find any issues you would like to have fixed, please let me know and I’ll happily respond to requests. If anyone would like to contribute in the form of a patch or just contribute in the form of ideas and feedback, It’s all welcome.

Brains is only about 2 weeks old since I started the clean new project and it’s still very much a work in progress so there are still lots of features I could add to this middleware component to make it more useful.

Brains Source ZIP Download

Brains SVN Root

In the project is the main BRAINSFramework along with the debug AIRendering project. A Gamestatemanagement library for setting up a new game quickly and the AIDemos. There is also a very primitive Behavior tree designer which I’m currently working on making more friendly and feature rich.

I will be writing more comprehensive documentation in due course along with some articles to accompany the BRAINS library.

XNA & Game A.I – Where to begin

Posted by – July 8, 2009

I’ve been thinking a lot about writing some articles on using A.I in games with XNA but I just don’t know where to begin. I have to start somewhere so let’s get to it.

As previously mentioned I’ve been writing an A.I library for use with XNA games. It’s called Brains and it consists of a few building blocks to get you quickly up and running with an A.I prototype and just as simple to implement right into your game. It’s currently only in 2D but would not require too much modification to support 3D.

The Brains library is built up of a world map, an A.I agent and a behavior tree implementation.

The Map

A world map is made up of a grid. In it’s simplest form a world map could look like this

image

It would be made up of 1 grid which is 16 GridCells and have 4 columns and 4 rows of GridCells.

A more complex world might have over 100×100 GridCells in it’s map. Brains can split this into a cluster for you which will greatly increase the speed of path finding and other A.I techniques. As a simple sample we could have a map made up of 8×8 cells and have a cluster of 4 grids.

image image

image image

In the real world they wouldn’t have a gap in between, this is just to represent that they are separate grids in a map cluster.

When loading a world map you simply specify the width and height of the map in world coordinates, pixels for example, the cell size to split the world into again in world coordinates and if you have a large world you can decide to create a cluster by specifying the rows and columns to split the bigger world into. In this example that would look something like this.

World.SetupMap(1280,1280,160,2,2);

You can also load a world map by loading from a texture. In the current implementation it will assume 1 pixel of the image to be 1 GridCell. Here is a blown up example of one of the demos in the source code.

image

Brains will set any pixel that is black, to be a blocked type of GridCell, and any other colour to be an empty GridCell. The red and green pixels are loaded and annotated on the grid for your use but are not used internally in the engine. This makes it super easy to knock up a quick map to test out.

The Agent

A Brains A.I world also contains a list of Agent types. This type is used to provide autonomous behaviors to your game. An Agent stores some simple positioning properties such as Position, Radius and the Cells the Agent is currently in. It also stores the desired orientation and the desired position of an Agent for use with a Locomotion controller.

An Agent can store a set of feelers which can be used by your behaviors to poke data around the world.

The last defining feature of an Agent is it’s RootBehavior property. This is an IBehavior type which can be any type of behavior built into Brains, or your own custom implementation.

You can inherit from the Agent type to give you that extra flexibility when creating your autonomous characters.

Locomotion Controller

The Locomotion Controller is what controls the movement of an Agent. This is isolated from the Agent so that you can extend and implement the default implementation to get your characters moving how you want them to. There are 2 types of LocomotionController implemented in Brains. The basic movement controller which moves the agent from its current position to its desired position, and rotates it to face the desired rotation. The other Locomotion Controller is the LocomotionSteering which will allow you to make use of the famous Steering Behaviors For Autonomous Characters by Craig Reynolds. My version isn’t quite finished yet as I’m working on a better group design but the basic steering behaviors are working at the moment.

Behaviors

Brains contains some built in behaviors to form the basis of any combination of behaviors you may ever need to build. You can of course ignore these and implement your own.

With the Brains building blocks you can quickly build very complex behaviour trees without writing a ton of spaghetti code.

A Behavior Tree is made up of smaller blocks of hierarchical logic and built to recursively go down the tree until it finds a behavior to run. A simple representation of a Behavior Tree can be shown like this.

image

The circles represent a behavior and the lines show how the behavior breaks down into active actions an Agent may take based on decisions further up the tree. The Behavior tree is a much larger the subject than the scope of this post though so I will brush over the behavior building blocks built right into Brains.

Sequence Behavior

The Sequence Behavior has a set of sub behaviors which will run the first item in the list until it is successful, it will then move onto the next behavior in it’s sub behaviours in sequence. If a behavior fails it will fail the whole sequence.

Selector Behavior

The Selector Behavior also has a set of sub behaviors which it will run in sequence until it finds a success and then complete as a success itself.

Random Behavior

This Behavior randomly selects one of its child behaviors to run.

ParallelBehavior

This is a very primitive implementation of a Behavior which will run multiple behaviors at the same time. This raises a lot of complications with access to current data so will currently prove troublesome if the parallel is not a simple one.

Condition Behavior

Used to provide conditions before running other sub behaviors

Task Behavior

This is the behavior which would contain your A.I logic code. You would generally inherit from this to provide the specific game A.I logic.

Combining these set of components with your own and your imagination you can create extremely complex A.I decision making agents with great ease. With the added bonus of a Behavior Tree designer provided with the source code it’s even easier to let you just put on your game d

esigner hat or give the ability to a game designer to create a better game A.I

Brains also contains a few Task Behaviors for pathfinding around the world. You can also extend upon these to provide more flexible pathfinding.

They are:

Find Path Behavior

Finds a path from 1 GridCell to another.

Follow Path Behavior

Follows a provided path.

GoTo Behavior

This behavior combines the FindPath and FollowPath behaviors.

FollowRouteBehavior

This Behavior takes a series of GridCells. It will pathfind from one GridCell to the next and cycle once it’s complete. This makes use of the GoTo Behavior.

 

That’s a brief roundup of what Brains has to offer. It’s still unfinished and will continue to get development done to it. I want to tidy up some of the API exposure I’m not happy about yet (a few dirty hacks) and then I’ll post the source code for you to have a play with and give me some feedback.

Credits

The majority of my A.I reading has been from the AIGameDev web site. I’ve learned so much from there, I highly recommend it.

Some other helpful sites are of course the XNA Creators Club Online

A few other XNA A.I related projects have also been a great source of inspiration. Most notably Simple AI Engine for XNA and SharpSteer

XNA & Game A.I

Posted by – July 7, 2009

Over the past few weeks I have been developing an A.I middleware library for use with XNA games. I’ve spent a lot of this time in google searching for A.I articles and samples. It’s a force of habit to append XNA to the end of my code related searches and I wasn’t finding the information I needed to get the inspiration for my A.I library. I did figure out how to use google eventually and found lots of good, general A.I articles and samples. Most samples are c++ but it’s more about the concepts of A.I I was looking for than the samples.

At some point in the very near future I will be releasing the source code to this library along with a sandbox for you to see how to use it and to play around with it. One thing I’m struggling with is deciding what small chunks of A.I I should demonstrate. If you have some ideas of what you would like from an A.I sandbox please comment on this post and we can discuss.

In the meantime, here is a bunch of links I’ve been reading over the past few weeks relating A.I and some XNA specific ones I did find.

 

XNA Creators Club Online

Other