2009
10.31

Virtually all programs have this, a central ‘game’ loop that grabs user input, updates game logic, redraws the screen. At it’s simplest possible level, it usually looks something like this:

repeat
   Input;
   Update;
   Redraw;
until Quit;

The problem mainly comes in that middle section, Update. For any game, there are a variety of different states you can be in (main menu, options screen, credits, playing game) and for most games, “playing game” breaks down into a whole lot more states by itself. For my simple 500 Card Game, I had states “bidding”, “dealing”, “choosing kitty”, as well as playing. If you’re not careful, your Update procedure can end up looking like this:

Procedure Update;
begin
   case State of
      STATE_MENU:
         // wait for a menu click
      STATE_OPTIONS:
         // handle user input
      STATE_CREDITS:
         // roll some credits
      STATE_GAME:
         case GameState of
            GS_PLAYING:
               // handle user input
               // update some monsters
            // etc
         end;
      // STATE_ even more stuff:
   end;
end;

So far, so big and clunky. It gets worse when you have to handle nested state transitions: in my card game, someone could be playing, then go to the Menu and come back. So I had to have a variable ‘LastState’ that remembered where they were, so they could go back to it. But it’s worse than that, because they might go to the Menu, then go to the Options screen: and when they came back, they’d still want their current game to not be lost! My card game was simple, so I managed this as simply as I could: when entering the ‘menu’ state, the menu grabbed it’s own copy of LastState, and it restored this value when the other screens (Options, Credits etc) returned to it, so there was always a way back to the game. This was the simplest case, because every state had exactly one other state that it could be transitioned from (you couldn’t get to Options from Game without going through Menu).

For Icefall though, the stakes were raised. I wanted the Options screen accessible from in-game, as well as in the initial menu. And there are many more states that the game can be in, and some of them should not be returned to (e.g the “create character” screen), so rather than a gigantic and ugly Update loop, I went back to good old OOP and implemented a class-based state stack.

Icefall has a central “State Engine” that looks after the current state stack, handles transitions between them, and calls whichever state is ‘on top’ during the main loop. The State class looks something like this:

TIceState = class (TIceClass)
   constructor Create
      (StateEngine: TIceStateEngine; 
       Transition: TStateTransition);
   procedure OnEnter; virtual;
   procedure OnLeave; virtual;
   procedure Update; virtual;
   procedure Redraw;
   // other useful state methods
   destructor Destroy; override;
end;

Essentially, for every state the game can be in, I have a corresponding class that defines it’s specific behaviour in Update. I can also do other ‘maintenence’ (e.g. ensure the right music is playing) by overriding the OnEnter and OnLeave procedures. The game can change states by constructing a new TIceState instance, passing it a reference to the state engine and describing the type of transition to use (e.g. whether to nest the state [for a trip to a Menu] or just progress to the new state with no way back [like a character create screen]). You can also leave a state just by destructing the class instance: the state engine will pop back to the next highest state on the state stack, or quit the game if there are no states left (e.g., you just hit ‘Exit’ from the Main Menu). 

The state engine takes care of nested states and transitions, and someone’s exact state in the game can be saved (if needed) by storing the entire state stack: while I’m unlikely to want the game to be saved while on the Character Create screen, it’s good to know I can safely save the game while in shops, or at any other point, without even worrying about special handling code to cover all the situations.

Another interesting thing I have done is move the game’s “loader” (the part that loads textures, sounds, music, fonts, databases) into it’s own state, and just made it the very first state that’s pushed onto the stack, and it takes a parameter to the state to transition to when it’s done. It takes the whole ‘loading’ step out of the main game code, which makes that much simpler, and I can make the loader just load the resources I’m going to need right now: some other state (like the credits) can always call it again later to load specific credit-y images.

I can also use the the same game engine to build other tools like the Map Editor: the only difference between the map editor and the game itself is that it compiles in a different set of states: when the map editor has loaded, it launches itself into a TMapEditorState instead of a TMainMenuState.

Overall, having a state stack is very flexible, quite simple to use and maintain, and overall a vast improvement from the ‘giant case statement’ I was using previously.

2009
10.30

Last time, we looked at the inheritance style of object-oriented programming in detail. Now let’s look at the alternative: composition.

We’ll use another example from Icefall to illustrate the differences. Icefall has a central ‘world view’ that shows the player and their immediate surroundings (items, monsters, terrain, etc). The world view also shows animations (e.g. fireballs, weapons swinging, speech bubbles, etc) and it’s the animation code that we’ll be looking at in detail today.

I designed this feature around each animation being a class instance, with the class methods and properties making it easy for the game engine to control the details (lifetime, location, save/load etc etc). I knew I’d have several different types of animation, so my initial implementation chucked all that ‘management’ functionality into a TAnimation class, and left virtual methods for  things like Process and Draw for descendents to implement. After creating a few basic animations, my class hierarchy looked like this:

TAnimation
   TAnimText
      TAnimSpeech
      TAnimTexturedText
   TAnimTexture
      TAnimMissile
      TAnimExplosion
      TAnimMelee

Animations with text (i.e. picking up an item) were a subclass, and speech bubbles (or text with a textured background) were subclasses of that. Missiles (like fireballs) were a subclass where the animation moved from one place to another (and was rotated to face the right direction), and Explosions were in one place but had a series of animation frames over time. Melee animations showed a weapon and some motion-blur, sweeping out to attack a monster/player.

The problem with this system, which I discovered after adding TAnimTexturedText (specificially to show damage-dealt as a number on a bloodsplat-graphic background) was that most of the subtypes only varied in very small ways, and the overhead of naming, constructing and using each subtype took more effort than defining the subtype itself. Also, the ‘event’ system I was setting up for Icefall was supposed to allow for animations to be defined dynamically in response to any spell or event (and new events added in data files without recompiling the game) – but the code that supported this was going to be very complex and ugly if it had to choose between all of the different constructors each time and pass a specific set of parameters to make it happen.

So, I rewrote the animation subsystem to bring any functionality that I could possibly re-use into the parent class: now, all animations had a Texture property, a Rotate property, Frames, Movement, Sound… which could all be left at Nil or 0 if not needed. My new, composited animation hierarchy looked like this:

TAnimation
   TAnimText
      TAnimSpeech

As soon as I did this, I found that it was not only easier to manage the sources, but that features of the parent class ended up getting used more often than I anticipated: e.g. giving an explosion a random value for Rotate made each explosion look slightly different, and I could apply a small Movement value to Text to let it ‘float’ upwards from where it first appeared: new and useful functionality essentially for ‘free’.

Note that I kept AnimText separate from the parent, because there is some substantially different functionality: it has text (which directly contributes to the size and position of the anim), which is also dynamic, and there is some special logic to ensure two text animations don’t overlap each other. It made sense to move this code out into a specific class where it could be closely tweaked. Speech is different again, because there is a “speaker” creature that it it linked to: the speech bubble needs to move around with it’s speaker, disappear if they die, etc.

In summary, now that the TAnimation class is composited, it’s significantly ‘better’ code than before:

  • Fewer types to worry about
  • Much easier to follow the logic of the code in a single class
  • Can trivially re-use functionality developed for one subtype in others
  • Much easier for other code to utilise this class effectively

So, my conclusion in this small series is:

Use composition in your classes, unless there is substantially different behaviour, or external code needs to interact with a specific subtype in a special way (e.g. TAnimation itself is inherited from TWorldObject, because the world view needs to interact with animations in a specific way).

Next time, I’ll find something different to ramble on about.

2009
10.29

This is all too common. You’ve developed some minor tool to meet a specific purpose, whether it’s a batch file, JavaScript, Visual Basic macro, whatever.

You know other people around the office will use your tool, but it’s not worth the investment in handling real error cases or writing proper documentation. Instead, you just throw in a message saying “If you see this message, talk to Jim!” , safe in the knowledge that all of the users are less than 20 metres from where you work.

Please, resist the temptation. These tools will often, completely by accident, end up with a lifespan that exceeds your term of employment! Two years later, this message pops up and confuses the hell out of the user.

A similar thing happened to a colleague of mine. A spreadsheet that ran a simple virtual-rugby sweep for his workplace, allowing users to enter their predictions and email them away. If a user tried to trigger the code to calculate the winner, they got a helpful dialog box: “Sorry, you’re not Jade Baxter! Nice Try”. Needless to say, after he left, virtual-rugby remained popular, and because he transferred to a different part of a large organisation, it caught up with him.

Now, we all use it around the office whenever any function or data is withheld from any person, for any reason, at any time. Sorry: you’re not Jade Baxter!

2009
10.28

Last time, we talked about two different approaches to designing objects for a game or application: Inheritance and Composition. It’s time to look at the pros and cons in more detail. Let’s start with inheritance.

Inheritance

When learning OOP, inheritance is what you learn! Create a common, generic ancestor-type class, and create new classes for specific game objects which inherit from, override and extend the functions of the ancestor. Repeat as desired. Let’s look at the consequences of following this model:

Pros:

  1. It’s easy to locate all functionality belonging to each type: they’re together in the source for the child class.
  2. It’s easy to write an appropriate constructor for the type; so you know the classes internal state will be consistent.
  3. It’s easy to guard against the wrong type being passed to a function at compile time: If you have Function AttackMonster(WithWeapon: TWeapon); the compiler will prevent you passing a TItem that isn’t a TWeapon.
  4. You can specify abstract methods in the parent where you know the divergent behaviour will be, and the language and compiler will help you get there and warn you if you’ve left something out.

Cons:

  1. You end up with *lots* of different classes – which may be in lots of different files.
  2. Some of the classes can be really, really small… e.g., a single method override.
  3. When looking at the child class implementation with a call to the inherited parent, you don’t know exactly what the parent does.
  4. If two different children of a common ancestor need the same functionality, you have to code it twice.
  5. Code that constructs instances must take care to call the correct constructor.
  6. You can’t “switch” a child to a different type; you need to destruct it and create a new instance of the other type.
  7. Greater risk of circular-references if your child classes need to interact with each other.

You can see the pattern forming. The Pros of this model tend to be that things are easier to setup up-front, when you’re initially coding the classes. The Cons tend to hit you later: when you’re extending functionality, or just coming back to the code after time spent elsewhere.

It’s also possible with this model to really make life impossible for yourself. If you come up against Con #4 and are tempted to move some of that common functionality in the parent class, congratulations: you just blasted Pro #1 and debugging and maintaining this code just became a nightmare, and now the parent needs to duplicate some child state in order to know which of these “optional-children” operations it should perform. Ick!

Note that this inheritance style is still arguably a gigantic code-safety and readibility improvement from old-style procedual code. The question is, can we do better? In Part 3, we’ll look at the alternative model of Composited classes.

2009
10.27

I’m working on the follow up to my Object-Oriented Programming post, but in the meantime I had to share this:

I tested Icefall on Windows 7 for the first time today (having developed & tested exclusively on Windows XP SP 3 up until now). It worked perfectly, in fact it ran a little more smoothly than it does on the same computer on XP.

It’s always reassuring when your application turns out to be forward-compatible, it’s a good sign my low-level code isn’t performing any horrendous unsupported operations, SimCity-style.

2009
10.26

Like almost everything else these days, Icefall is designed around object-oriented programming (OOP) principles. Specifically, Icefall uses Classes instead of objects, although the difference is not relevant for this discussion.

At any given time, the game will be operating dozens of different classes and hundreds of instances of those classes, with the majority of them representing either individual game objects (an item, a monster, the player) or a piece of the user interface (a button, an animation, etc). As you’d expect, many of these classes inherit from other classes (e.g. the button class is inherited from the generic UI class) but the question of exactly how much inheritance to use is something that confuses many people – and if you get it wrong, your code will suffer. So let’s take a closer look.

Inheritance vs Composition

Turning a program’s logic into a group of classes seems easy (hmm, my game has items, let’s make a TItem class!), but choosing the right combination of classes is harder than it looks. Like everything else, the more complex your application is, the harder and more important these choices will be.

One common choice is to do everything via inheritance. You make some ancestor classes which contain only the logic that will be common to all descendents, and you create inherited classes to cover all exceptions or additions to that logic. This style is called inheritance for obvious reasons, and lots of newcomers to OOP start like this. Let’s create an example that shows this in action:

Icefall needs to know an item’s worth (in gold) to a shopkeeper to allow the player to buy/sell it. As items in Icefall can have randomly generated properties, we can’t define the worth of everything at compile time (and even if we could, there will be hundreds of different items in Icefall. Don’t specify things you could calculate. I’ll talk about this another time). So we need a method in the TItem class to calculate the item’s worth for us.

Inheritance

The inheritance solution might look like like this:

TItem = class
   function Worth: Integer; virtual;
end;

function TItem.Worth: Integer;
begin
   result := ILevel * 20; // ILevel is another property.
end;

Nice and easy so far. The item’s worth is calculated as being 20 times it’s ILevel (item-level). But what happens when we want to make some items (let’s say weapons) more valuable than others? The inheritance solution is to build on the existing code and do this:

TWeapon = class (TItem)
   function Worth: Integer; override;
end;

function TWeapon.Worth: Integer;
begin
   result := 100 + ILevel * 50; // Weapons are worth more
end;

We have overridden TItem‘s Worth function with a new one just for TWeapon. We just have to remember that when we’re creating items, if it’s a weapon we need to construct a TWeapon class instead of a TItem class to hold it, and the right Worth function will be called automatically.

Composition

Meanwhile, another style, often referred to as composition, says to group similar functionality together, and use members or properties to determine the appropriate behaviour for each instance:

TItemType = (ITEMTYPE_NORMAL,ITEMTYPE_WEAPON);

TItem = class
   function Worth: Integer;
   property ItemType: TItemType;
end;

function TItem.Worth: Integer;
begin
   case ItemType of
      ITEMTYPE_WEAPON :
         result := 100 + ILevel * 50;
   else
      result := ILevel * 20;
   end;
end;

Already, for our tiny example, the two implementations are looking considerably different. The composited version defines a class property called ItemType that stores what type of item this instance represents, and the Worth function contains all the functionality for both item types (I used a case statement instead of a simple if, because I suspect I will end up with more than two item types).

p.s. Icefall, of course, takes much more into account to determine an item’s worth: it’s rarity, any enchantments, whether the shopkeeper likes the player, etc etc. But that wasn’t relevant for this discussion 😀

Conclusion

So which is better? What are the pros and cons of each style? Tune in next time to find out!

2009
10.24

The next step in Icefall’s development was to decide whether to make the game realtime (like Diablo, Titan Quest, World of Warcraft…) or turn-based (Angband, Nethack, Ultima 1..5). This is probably the biggest decision for a role-playing game, as it dictates the entire gameplay, as well as the UI, multiplayer, everything.

Initially, I looked at real-time. This is the only choice for multiplayer (turn-based multiplayer just doesn’t flow) and all of the ‘modern’ games follow this formula. So I developed a playable prototype along these lines. While still using a tile-based world, this would allow freeform movement (characters were not tied to specific ’tile’ locations), and could have supported multiplayer quite naturally. Using placeholder graphics borrowed from games, I developed a prototype game that ran in real-time:

Prototype of Icefall in real-time

Prototype of Icefall in real-time

The prototype accomplished it’s goal, which was to determine whether real-time was feasible, and what the challenges would be. After getting the prototype running with some simple monsters, I had figured out the challenges I would be facing:

* Pathfinding dozens of monsters around a complex environment, in real time, is very hard.

* Real-time locks you into a specific travel speed, and can make ‘huge worlds’ time consuming to explore.

* It was very hard to find the right ‘game speed’. Too slow and players get frustrated and bored. Too fast and the monsters can kill the player too quickly. I wanted players to dictate the pace: in Angband, you can play it very quickly or very slowly. I couldn’t find how to do that with real-time (a “game-speed” slider would not accomplish this).

* It just didn’t feel like the game I wanted to make. (I have played too much Angband).

* It didn’t quite ‘fit’ with other concepts I had already thought about, as well. e.g. I already knew that I would be implementing a ‘monster memory’, which tracked monster kills for players and stored any weaknesses/vulnerabilities/etc the player observed. With a real-time game, I couldn’t figure out how the player would access the monster memory without pausing the game (which would be ugly for multiplayer) or just looking it up academically after the battle was already over (not very useful).

Making the decision to go turn-based was a big ‘constraint’ in itself, but with the decision made, it makes many many other features much easier, and seems to make the player’s overall experience more relaxing.

This final key decision having been made, I was ready to start some actual coding. Next time, I think I’ll mix it up a bit by looking at an actual code sample…

2009
10.17

I am currently working on a new role playing game called Icefall, and to help maintain clear thinking, correct decisions, etc etc etc, I’ve decided to document the development journey on this website as a blog. That way, once Icefall is released and becomes hugely popular (:D), I will have a solid record of how it happened. As the game is currently about 25% complete, it’s a good opportunity to summarise the progress to-date and take a look at the ‘big’ decisions, which have already been made:

Decision: Role Playing Game

Many of the very first games I got hooked on were RPGs: Moria, Ultima 5, Death Knights of Krynn) but each of them always had things I thought “if only it did…”, so creating my own game would be my opportunity to put that into practice. I’ve started to create many RPGs over the years, but I’ve never finished one or even got it largely playable. This was due to various different causes, either I’d hit a wall somewhere (pathfinding, AI, memory, and graphical speed have all defeated me over the years) or a new game (Halo, World of Warcraft) would come along and I’d abandon my development for long enough that I forgot the intricate workings of the code, and rather than dive back in I abandoned it.

So I’ve still never made a role playing game. Time to fix this!

Another good reason is that it’s within my ability. Making something like a first-person shooter (at least, a good one!) just wouldn’t be possible for me because having decent graphics is too large a part, and my graphical ability… well, let’s just call it “Programmer Art” and move on.

Decision: Free Pascal

Having decided on the type of game I’m making, the next step is to choose the programming language. These days there are more languages than ever, and some of the new ones are really good. C# + XNA would be my ‘high level’ choice, it makes it ridiculously easy to get graphics on the screen and a game up and running…

But…

I’m not just programming to make a game, I’m also doing this because I want to be challenged. I want to take fundamental, low-level control over everything my code does in every situation. Using a low-level language (C++, Pascal…) means there’s a lot more up-front effort involved (getting graphics on the screen isn’t one line of code anymore, it’s a couple of hundred) but, to me, also much more satisfaction when it works!

When I want to add a function, I can’t just copy a C# code snippet from the internet, I’ve had to go away and install the DirectX SDK, read the documentation for each instruction, look at the example code, re-interpret it to suit what I’m trying to do, and play with it until I get it to compile. The reward (and the knowledge that is acquired as a consequence of having to research every call) is worth it. (This is the same reason I’m not using an existing ‘game engine’, I’m creating my own with LX7).

Having decided to use a low-level language, my choices are C++ and Pascal (I don’t want to learn another language at the same time as creating a complex game, the game at the end would suffer too much as a result of my learning-while-doing). I chose Pascal because, I’m not really sure why, I just “like it”.It has all the language constructs I’m going to need (primarily Classes), and I like that it’s not quite as low-level as C++, which gives me a little bit more room to spend on game logic but without having to sacrifice anything.

Finally, choosing between my Pascal options, FreePascal and Delphi… I think FreePascal is superior! It definately compiles faster and makes smaller executables. It doesn’t support Windows GUI very well, but Icefall like 99% of games will have custom UI anyway. It’s also free. Finally, the platform is far less common than C++, and there aren’t many games in development using it (especially on Windows), so when the game is done and LX7 (the graphics/game engine I’m creating to support Icefall at the same time) is finished, I might have something to give back to the FreePascal community. So it’s settled!

Next time, I will talk about the third key decision for Icefall: whether to make it real-time, or turn-based?

2009
10.16

Paradice Software website makeover

To cope with the huge expected demand for information about Icefall (hahaha), I thought it was about time I updated the website, as the old one was created in Notepad using handcrafted HTML over ten years ago, and it hasn’t aged well!

I am slowly working around to migrating the site to a CMS (I want to design it myself, to improve my ASP skills, so it will take some time). In the meantime, the least I can do is update the styles a little so it’s not quite as painful to look at. The main news page is using WordPress, so at least it’s searchable / RSS enabled.

Going forward, here is where I’ll try to blog about the development of Icefall, including the challenges, decisions, and anything else that seems relevant. If you’re interested in the non-professional game development process, hopefully this should make a good read for you!

Archives, Old Content…

If for some strange reason you want to look at the previous News content of the website, this is The News Archive link.

Some people may also still find The CPUID Guide handy, although it hasn’t been updated in several years.

I have updated the About and Links pages to remove obsolete information. The “Projects, Guides and LX5suite” are still way overdue however!