Making a shiny new axe

First, some true back-story:

You probably already know that XML was designed as a storage format by the computer hardware cartels in order to maintain a high demand for enterprise grade storage and XML accelerators. You may also know the only reason JSON exists as a data interchange format is because it requires very little grey-matter straining to manipulate using JavaScript. I may well be corrected, but YAML appears to exist only to have hilarious unbounded fun trying to explain to non-techies what “Significant white-space” is. These formats excel in their own little niches, they also happen to suck pretty tremendously when used outside of said niche.

Why make your own format?

With requirements for serialization of various game resources in my game engine I needed functionality that isn’t possible in any of the above and that a tailored format was needed. Also, I thought it sounded a pretty cool project.

List of demands

  • Lists, dictionaries, strings, floats, bools – all the stuff you’d expect.
  • CDATA-style blocks. Chunks of strings with no concerns over escaping or other such shenanigans.
  • In-line comments and block comments. Configuration files in particular can be very complex, and containing documentation alongside the variables is double plus good.
  • It has to be as easy to edit as possible. I dislike syntax saccharin and wanted something as clean as possible.
  • It’s mine. NIH is awesome right?

Is it ready to use?

Yes, if you’re a masochist and/or just can’t help yourself. The parser works fine, but you’ll be casting from object all over the place. Object serialization and de-serialization is on the list, as in better handling of malformed input – Check GitHub for an up-to-date roadmap.

Where can I get it from?

The easiest way is via nuget:

PM> Install-Package Hatchet

Or, head over to GitHub and clone the repository.

Just show me the codes

Here is an example file format:


{ // open object definition

  name "Hatchet" // double-quoted string
  author 'Dale Reidy' // single quoted string
  isAwesome true // boolean
  cost 0 // integer
  durability 9001 // todo: nerf durability?

  description ![
     This is a block of text.
     It can span multiple lines.
     And contain "huge" amount of text.
     !] // a block of text

  versions [0.1 0.2 0.3 0.4] // list of floats

  tagcloud ['json' xml "data-storage"] // list of strings. 'xml' is implicitly parsed as a string

  dependencies [ // a list of objects
    { name "nunit" version "2" } // notice lack of comma
    { name "fluentassertions" version "" } // todo: find actual version number
  ]

} // close object definition

You can parse it like so:


// Valid for release 0.0.0.1.

public void ExampleParsing()
{
    var input = File.ReadAllText(@"c:\that-block-above-this.txt");
    var result = (Dictionary<string, object>)parser.Parse(ref input);

    var parser = new Hatchet.Parser();
    var author = (string)result["author"];

    Console.WriteLine("Hatchet was made by {0}", author);
}

Ludum Dare 30 – Just getting stuff done.

A few weeks ago I decided to take part in LD30 (For those who don’t know – Ludum Dare is a game development competition where solo developers have 48 hours to create a game centered around a theme).

I made the flip decision midday Saturday to take part: I was watching Markus Persson (Notch) construct what would eventually become billboard-grass-simulator-2014 and eventually “dark”, and wondered why I was watching somebody else make something, when I could be making something too!

So… My objective entering LD30 was to crack on making something and “complete it” – that somebody could start the game, follow a basic tutorial, be reasonably engaged with the game mechanics, and win (hopefully losing a few times beforehand whilst still retaining enthusiasm for continuing). I knew the graphics would be primitive, the sound would be non-existent, and my choice of genre wouldn’t appeal to everyone, but I didn’t really care too much about that, I just wanted to listen to Electro House and make something.

Screenshot of my LD30 entry

My LD30 entry – click to play!

The game was made using HTML5’s Canvas, JavaScript, and a little bit of CSS, simply because I didn’t want to mess around with any 3rd party libraries, or clutter my mind with having to fix bugs whilst referring to bad or non-existent documentation. My objective was to pick a reasonably detailed game mechanic which would need me to do nothing else other than blit sprites and write game logic. There’s so many hobby gamedev projects I’ve started and not finished – despite learned lots from making them so few have actually been bundled up as a playable game.

At the end of it, my actually-rather-difficult strategy game came in at 446 out of 1493 which I’m pretty chuffed with, though I didn’t have enough time to play all the other 1000 or so games created by others – check the other games out here.

And make sure LD31 is in your calendar.

Reporting in

A progress update – The terrain rendering has been improved to the point where I can stand to look at it – it’s now lit, is multi-textured and has some grass clutter. I created a robot model which replaces the old zombie, so now it’s a game with legit robots.

2013-06-11-2315

Heightmaps and Collision Meshes

2013-05-19-1713-terrainCollision2-resized

Heightmap calculation is complete along with terrain following for mobs and the player.

logo and typeface

Some images, as the height map generation is still a WiP, so no new screenshots…

First version of the logo:

logo2-600

And a type face for the HUD:

font-trimmed

RRROBOTS!

RRROBOTS! is my new project, and is currently at a ripe age of 3 days. It’s partly 3rd person shooter and partly tower defence game, the objective is to kill all the RRROBOTS! before they get to the underground human city and kill everybody. Here’s what it looks like at the moment:

2013-05-13-1945

Legume 0.5

I’ve updated legume to version 0.5 which contains few changes but importantly now works in OSX. The [google code project page] contains the installers, and the source repository has been migrated over to [bitbucket] purely because I like it more google code, which hasn’t aged particularly well.

Pre-multiplied alpha

Pre-multiplied alpha is alpha blending done correctly. It involves changing your alpha blending states, and ensuring your texture colour channels (R, G, B) are pre-multiplied (hence the name) with the alpha channel (A).

Firstly the alpha blending operations will have to be changed:

  • Set your source alpha blend to ONE (probably instead of SRCALPHA) – How solid our source texture appears depends on our alpha value alone (pre-multiplied colour channels at work here).
  • Set your destination blend to INVSRCALPHA – The more solid our texture appears, the less light we should let through from behind
// Standard fare alpha texture operations
Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);

// Important
Device.SetRenderState(RenderState.AlphaBlendEnable, True);

// New alpha blending render states
Device.SetRenderState(RenderState.SourceBlend, Blend.One);
Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);

The next part is loading the texture data and calculating the new colour channel values – below is a C# snippet for reading a 32-bit bitmap and performing this calculation. We take a bitmap that has been loaded into memory, iterate over each pixel in the image, calculate our new R, G and B values and save them back into the bitmap. Using SetPixel and GetPixel would be far too slow so this example locks the bitmap data and accesses the colour values directly.

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct RgbaColor
{
    // Huh?! turns out PixelFormat.Format32bppArgb should
    // actually be called Format32bppBgra.
    public byte Blue;
    public byte Green;
    public byte Red;
    public byte Alpha;
}

public unsafe static class DangerousTextureLoader
{
    private static Texture LoadFromBitmap(Bitmap bitmap)
    {
        // Lock the entire bitmap for Read/Write access as we'll be reading the pixel
        // colour values and altering them in-place.
        var bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                     ImageLockMode.ReadWrite, bitmap.PixelFormat);

        // This code only works with 32bit argb images
        Debug.Assert(bmlock.PixelFormat == PixelFormat.Format32bppArgb);

        var ptr = (byte*) bmlock.Scan0.ToPointer();

        for (var y = 0; y < bmlock.Height; y++)
        {
            for (var x = 0; x < bmlock.Width; x++)
            {
                // Obtain the memory location where our pixel data resides and cast it
                // into a struct to improve sanity.
                var color = (RgbaColor*)(ptr + (y * bmlock.Stride) + (x * sizeof(RgbaColor)));

                var alphaFloat = (*color).Alpha/255.0f;

                (*color).Red = Convert.ToByte(alphaFloat * (*color).Red);
                (*color).Green = Convert.ToByte(alphaFloat * (*color).Green);
                (*color).Blue = Convert.ToByte(alphaFloat * (*color).Blue);
            }
        }

        // SlimDX specific stuff here
        var newTexture = new Texture(_device, bitmap.Width, bitmap.Height, 0,
            Usage.None, GetD3DFormat(bitmap.PixelFormat), Pool.Managed);

        // SlimDX specific stuff
        var textureLock = newTexture.LockRectangle(0, LockFlags.None);
        textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride);

        // The bitmap lock is freed here
        bitmap.UnlockBits(bmlock);

        // SlimDX specific stuff
        newTexture.UnlockRectangle(0);
        newTexture.FilterTexture(0, Filter.Default);

        return newTexture;
    }
}

You can read a better explanation and a link to a research paper at TomF’s tech blog. He also highlights how pre-multiplied alpha will help compress your textures using DXTn formats.

Daybreak

I’ve been spending the past few months working on a top-down zombie survival co-op game, it’s still very much still in the workshed.

This game, whilst rather rudimentary in it’s presentation, is actually designed to be a realistic zombie apocalypse survival simulator. We used a team of zombie survival experts* to plan situations that would call for coordination, teamwork and an assortment of firearms and melee weapons.

* they watched Dawn of the Dead once or twice. We did try and use somebody who’d watched Resident Evil 2, but he was past saving.

Microsoft certification

Last month I finished my second exam [70-562] – this means I’m now an MCTS in developing ASP.net Web Applications(hurrah!), unfortunately I have to print my own certificate (boo!).

I got quite a lot out of reading through the self paced training kits – though they’re DULL AS HELL, and full of errata. Lots of little unknown unknowns in my knowledge of C# and ASP.net got patched, and I learnt quite a bit about stuff I have never come across in my job or in my spare time.

The big downside to taking the examinations is the interface you’re forced with using – it’s bloody awful. Lack of mouse-wheel enabled scrolling of the question and answers, 800×600 resolution, no option to switch mouse buttons for lefties (minor point but still, it was a bit frustrating), and a strange UI behaviour where, if you click a radio button of a selected answer, it deselects it! – so my belt&braces OCD make-sure-I’ve-clicked-my-correct-answer method caught me out a few times. Despite the unnecessary hurdles, I made it through – seriously Microsoft, fix the interface.

Project-wise, I’m currently working on a top-down multiplay zombie shooter – Its in it’s infancy at the moment but you can find some early screen-shots on the Daybreak project webpage.

Legume is on hold for the meantime – it’s not dead – unlike zombies – which are.