Friday 23 August 2013

Room generation - part 1



This post is all about how the rooms are created randomly in LOTWK.  It’s a pretty extensive subject, so I’ll divide it up into two meaty posts, instead of one giant one.  The first step for the room generation in LOTWK is to create the room shape, which we do by placing the floor tiles.  The result of this first stage looks something like this:




The floor tiles are placed based on some descriptors in the XML data files.  These descriptors set out some simple factors such as how many blocks of tiles to place, their approximate size, and any limitations on where and how to place them.  The details are pretty dull, so I’ll just throw in this example XML and you can pick it apart yourselves:


<room name="test room">
                <mainBlock width="12" height="12" />
                <block1 width="8,8" height="10,10" count="1,2" angle="180,180" tag="x" />
                <block2 width="3,3" height="10,10" count="1,2" angle="180,180" startType="previous" />
                <block3 width="8,8" height="4,4" count="1,1" angle="90,90" startType="tagged" tag="x"  />
                <block4 width="6,6" height="4,4" count="1,1" angle="90,90" startType="previous"  />
                <block5 width="2,4" height="2,4" count="4,8" startType="random"  />
                <columns1 width="2,2" height="2,2" count="1,3" buffer="3" />
                <templates1 category="furniture" count="4,12" tags="normal,desks" />
                <templates2 category="furniture" count="4,12" tags="normal,benches" />
                <templates3 category="loot" count="1,4" />
                <templates4 category="decor" count="5,15" />
                <templates5 category="structural" count="1,5" />
</room>



                As you can see, there are a series of “blocks” elements, and it is these that describe the approximate shape of the room.  Each location theme (snow caves, forest, dungeon, etc) will have a large variety of room styles described through XML “room” nodes, so that a noticeable variety of rooms exists, instead of them all being hewn from the same cloth.

                The next phase is to throw in the walls.  This is pretty straightforward – because the room is tile based, determining which tiles should become walls is a simple matter of finding floor tiles with empty tiles adjacent to them.  Corner wall tiles can be identified in a similar way.  This results in something like this:



                Gah!  What’s with the six bajillion lights on the walls!?  This is how LOTWK determines where to place wall-torches and other wall-mounted light sources.  Each wall segment is a template (a group of objects) which gets placed.  This allows for things like paintings, banners, torches, and all other manner of objects to sit neatly aligned with the walls.  Because the walls can be any shape, a system that tried to automate placement of objects on walls would result in a lot of ugly clipping issues, or worse, floating objects!  So we use a template grouping approach, where templates are randomly placed for each wall segment, including wall decoration and lighting.

So the next phase is to clean up all those extra lights.  This is dead simple – the game iterates through the lights and deletes those that are too close together.  The end result is something like this:



Next up we need to fill in dark areas.  These dark areas are created because there are no nearby walls, and therefore no wall-mounted light sources to fill the darkness.  So let’s place some floor-based light sources.  And while we’re at it, let’s also extinguish a few of the existing light sources to add a little variety.  The result looks something like this:



The room is still very barren though – it’s just walls and light sources.  It needs some furniture.  This is achieved in a similar fashion to the wall placement – it uses template groups of objects and tries to place them around the room.  An example grouping might be a writing desk, which would consist of the desk, a chair, the quill and ink, and perhaps some scrolls of paper.  These items are all grouped together in a template data file, so that the game engine can then attempt to place them all together up against a wall.

This brings me to the real power of the template system – placement types.  Each template group has a placement type variable associated with it, which tells the engine how best to place the template in the room.  These types are things like “up against a wall”, “in a corner”, “in open space in the middle of the room”, “between two walls”, or “tucked away in an alcove”.  By only allowing a template to be placed in a specific fashion, it prevents weird situations like a bookshelf sitting alone in the middle of the room.  With some furniture thrown in, the room looks something like this:


(note, the game is still early in development, so there is not much furniture to place yet, and so the room is still quite barren with only a few rotting desks and some pipes on the wall)

The final stage of room generation is to make the room look a bit prettier.  This is done through floor patterning and edge bordering.  Floor patterns work much as object templates, but instead of a group of objects, it’s a group of floor tiles which get placed around the room.  The bordering is where the game detects the tiles that run alongside the walls and makes them into nice border tiles, which makes the room look like it was designed rather than thrown together using a random number generator.  The result of the floor additions looks a bit like this:



And there it is; a room with stuff in it and torches on the walls.  What more could a band of psychopathic, money-hungry adventurers ask for?

Next time I’ll go into the specifics of how monsters are selected for placement in the room, and how the game will try and balance the room layout with the type and quantity of monsters.

Saturday 3 August 2013

The data driven approach

What is the data driven approach, you ask?  In a nutshell, it means using information instead of code.  There are many places in game development where you re-use a lot of the same basic mechanics and build up variations through small changes in the data.  For example, the difference between a male barbarian and a female barbarian would be small stat changes, a different mesh, and a few other changes like name and the noise s/he makes when hurt.  The actual code that handles all these aspects does not change, all that changes is the data.

Friday 5 July 2013

To thwack or not to thwack



               This post is going to be delving into the murky depths of the melee combat system inside Last of the Warlock Kings.  I really wanted the melee In the game to be more than the rubbish standard you see in so many RPGs and turn based games.  You get a basic swing of a sword, and a basic pain animation plays in the target.  Or worse still, you miss, but the same attack animations play out and your sword goes through the target character – what sort of a miss was that!?

Friday 21 June 2013

To automate or not to automate

This post will be about a very simple thing to implement, but which can save a lot of time - data automation.
   
    The biggest hurdle to a game like Last of the Warlock Kings is the sheer amount of 'stuff' you need to put into the game.  When you combine this with the data driven approach (a necessity when you want to make the game very mod friendly) you quickly find yourself making a ton of data files, all of which share a lot of the same content.