2009
11.30

Because screenshots are always interesting, here is a screenshot of the “Character Creation” part of Icefall. This is one of the very first screens new players will see, as they opt to begin a new adventure the first thing to do is decide who they’re going to be. (I deliberately replaced the description text with Latin, don’t want to give away too many plot points at this stage!)

Icefall Character Creation, Nov 30 2009

Icefall Character Creation, Nov 30 2009

Note: the “portrait” is currently a giant, upscaled version of the tiles used for the characters ingame. I would love to have larger character portraits, but my artistic skill just isn’t there…. hopefully I will find or convince someone at some point to help out ūüėÄ

Class Selection

In Icefall, Class is a much more important choice than Race: Race has a few minor effects on stats, starting location, etc, but Class affects how you will approach the game: how you will defeat monsters and complete quests.

I strongly considered a “class-free” model, where the player starts with a generic character and shapes it over time just by their choices of equipment and ‘specialisations’ (Titan Quest is a good example of this approach), but it made things too complicated, and you don’t gain too much in the approach anyway: in Titan Quest, if you don’t specialise correctly, you’ll end up a sort of “jack-of-all trades” type character who is not good enough at any one thing to get very far. So you may as well make the choice up-front, so that you and the game can work together to give you the type of experience you want. Choose a Ranger? Great, I’m going to give you some ranger-related quests.

2009
11.27

I took a few days’ break from Icefall to develop a quickfire helper application for myself (a simple media-centre type program to organise, search and filter the various videos and music I have lurking around, with a few handy unique features like automatic IMDB-Lookup for descriptions, saves me typing them off the DVD cover).

After working on Icefall for so long, I was amazed at how quickly I was developing the code for the new program! When writing Icefall, I might create a single new source file in a night’s work, or maybe make 4 or 5 moderate improvements to existing code. On the media app, I was churning out half a dozen new source files at a time, and I had the entire application virtually finished in about three days.

Thinking about my observations of the difference, I eventually came up with the following formula:

Development Speed = Effort / (Complexity * Quality)

For a given amount of effort, I can get a lot more done on the media app, because A: it’s far less complex, and B: I care much less about the quality of the code. Multiply those factors together and you can see why Icefall development is approximately an order of magnitude slower: it’s a complex system, all the code has to be correct, robust, speedy, and extensible.

I’m convinced this is part of the reason why so many “we’re going to create the perfect application, that does everything and is open source” projects never reach version 1.0. With all the effort in the world, they’re just throwing huge numbers on the wrong side of the divisor.

2009
11.21

Taking a break from coding topics, today’s post explores how Icefall’s dialog User Interface (UI) has evolved over the course of it’s development. My automatic-backup tool keeps every version of Icefall available, so I fired up a few old versions and took some screenshots to illustrate the process.

Original Design

UI Dialog: Original

This screenshot is actually from the realtime Icefall prototype. I needed a quick way to change screen resolutions for testing, so this is it. Some interesting features: The green background would slowly sway while the dialog was open, and there was a shimmering gold border around whichever element had keyboard focus.

Revision

Icefall: Revision

Fast forward to the turn-based rewrite of Icefall, and this is the original Video Options dialog. Some big changes: the background texture is more subdued, there is a panel on the left to select what type of options to view, and the gold-edge focus indicator has gone (now, the focused element is just highlighted a little more). Buttons and checkboxes have also had a minor makeover, e.g. the buttons are now rounded.

Revision 2

UI Dialog: Revision 2

What changed here?¬†The window frame! Gone is the ‘rusted steel’ frame from the top and bottom of the window, replaced with an ice-blue frame that encloses all four sides. I wanted to get more “ice theme” into the UI for the game,¬†and at the same time I¬†needed a UI frame that covered the left and right too, because not all UI elements use the slate background¬†(the spellbook, for example, uses a ‘book’ background, and it looked a little strange with no enclosing frame). I also think this looks¬†better than the¬†previous¬†one.

Current Design

UI Design: Final

Good, the rate-of-change of the dialog is slowing down, which means we’re getting closer to completion! The only change here is to the background of the listbox. The ‘green waves’ looked ok in the original version, but as the¬†look and feel of the rest of the dialog evolved, it began to look more and more out of place. When the dialog frames turned ice-blue, it was a good opportunity to build on that existing colourspace and again lend more of an ‘icey’ theme to things by using a dark, ice-blue texture. This is what this dialog looks like in current builds. Hopefully, you agree with me that it’s the best looking of them all?

2009
11.18

Icefall uses literally dozens of textures… (and it will probably be ‘hundreds’ by the time the game is completed).

Textures are used for everything, from the mouse cursor, menus, fonts, buttons, to the game world itself, spells/action icons, monsters, equipment… everything.

Although my own main PC has 512MB of video (texture) RAM, not everyone does! And
following on from my minimum requirements post, I don’t really want someone’s video card memory size to be a limiting factor if everything else meets the requirements, so Icefall needs a way to manage things when there are more textures than there is video memory.

I don’t want each bit of code that uses textures to worry about whether they’re loaded or not, so the logical choice is to encapsulate all of the texture handling into one place: I call the class that handles this the TContentManager (“content” because it also handles sounds, fonts, music, etc.).

When the game code asks the TContentManager for a texture: the first thing it does is look to see if that texture is already available in video memory: if so, it just hands out a reference. Easy! If not, it retrieves the filename for that texture from Icefall’s ResourceDatabase, and attempts to load the texture from disk. If that fails, it looks at why it failed: if it’s D3DERR_OUTOFVIDEOMEMORY, the next step is to unload some other texture and try again, repeating until the load succeeds or we have no loaded textures left. (If it still doesn’t load, or if the texture load fails for some other reason, it’s goodbye Icefall).

Programmatically:

function TContentManager.GetTexture(ID: TTextureID): TLXTexture;
var
   HRes: HRESULT;
   NewTexture: TLXTexture;
   FileName: String;
begin
   if TextureLoaded(ID) then
      exit(Texture[ID]);

   FileName := ResourceManager.Textures[ID].FileName;
   repeat
      HRes := LXLoadTexture(FileName,NewTexture);
      case HRes of
         D3D_OK:
            Texture[ID] := NewTexture;
         D3DERR_OUTOFVIDEOMEMORY:
            UnloadTexture(0);
      else
         // Fatal error!
      end;
   until TextureLoaded(ID);
   result := Texture[ID];
end function;

UnloadTexture is a method that unloads a texture. It takes a TTextureID as a parameter, but passing 0 in this case tells the method we want it to choose a texture to unload itself. This is where it gets interesting.

Before I got to this, I originally had set up a few states so that they explicitly called TContentManager.UnloadTexture to release textures when the game left that state (e.g. the game would unload the ‘Option-selection’ texture when the player closed the Options dialog). However, this turned out to be sub-optimal for several reasons:

  • Players might well leave and re-enter states (like Options) several times to accomplish whatever it is they’re trying to do.
  • It doesn’t make use of extra video memory: it keeps loading from disk (or the disk-cache anyway) while the extra video memory stays idle.
  • I had to explicitly declare what textures I was done with. Not a problem really but ‘just another thing’ that I had to do when changing states.

So now I no longer explicitly release anything. UnloadTexture always chooses the texture to unload that was least-recently used (a linked list makes this a very fast and efficient check – no timers or array scanning involved). In practise “least recently used” turns out to be about 97% optimal (when simulated against a 100% optimal algorithm which is permitted to see the future when deciding what to unload) so it’s virtually perfect – substantially better than my explicit declarations were.

If for some crazy reason the user doesn’t want Icefall consuming all of their video RAM*, I can chuck in a call to IDirect3DDevice9.GetAvailableTextureMem and trigger UnloadTexture if it’s below some specific amount. Alternatively, I could keep a sum of the amount of texture memory I’m using, and trigger UnloadTexture if that amount threatens to exceed 32MB or whatever (I haven’t decided yet).

The point is, if you find yourself manually balancing resources, it’s probably an excellent idea to profile your resource usage and see if you can find a pattern that will let you just automate the whole thing**. You’ll save yourself much time and your code will be cleaner and more flexible.

*Note: this only actually matters on Vista or Windows 7. Under the Windows XP model, multiple applications can’t share texture memory anyway. As soon as an application takes focus, DirectX invalidates all texture resources belonging to everything else (forcing them to reload from system-memory or disk when they get restored). The WDDM (Windows Display Driver Model) in Vista “understands” video memory, and can share it amongst applications. This is one of the reasons DirectX 10+ can’t be backported to XP: XP has no concept of video card resources.

**If you’re creating a game frame-rate locked or just frame-rate dependent, you might still need to explicitly acquire and release resources (e.g. between levels), because a 10ms pause at an unexpected point in your game could be noticeable or detrimental. Either that, or move the resource acquistion to another thread and have low-quality ’emergency’ textures to display while the real ones load… this is a very common technique for FPS games.

2009
11.16

I’m currently reading a book about the evolution of Windows. One of the most interesting things I keep finding is how stupid some 3rd party application developers must have been…. for example, it seems to have been common practice that if you wanted your app to grab a particular Windows setting (let’s say the Fonts directory), instead of a quick MSDN search, which turns up both the SHGetFolderPath and SHGetKnownFolderPath functions (either of which is exactly what you want), these programmers fired up RegEdit and searched for the path of their own Fonts folder… the first key they found, they used as the parameter for a call to RegOpenKeyEx and they read the value that way.

To me, that is not only a frighteningly ignorant and dangerous way to develop software (you’re not going to discover caveats & usage notes by browsing RegEdit!) but of course this is not the supported way to do it (how could any sane developer think otherwise?), and of course that app would have broken immediately on any new of Windows had MS not added a compatibility shim to watch for that program checking that buggy key, and substituting in a quick call to obtain the real value…

This isn’t backyard programmers writing in VBA in Excel to accomplish some one-off business task, either.. it’s commercial software that did this, written by professional developers and sold to unsuspecting customers for big cash. Scary stuff.

The only question worth pondering here is: was this ‘grab something promising out of the Registry’ technique better or worse than just hard-coding “C:\Windows\Fonts\” into the application? (I’m not 100% sure but it seems very likely there’s a shim out there for programs that did that, too.)

2009
11.12

I thought I’d cover this rule first, because I listed it as number one and also because it’s probably one of the most controversial. Let’s begin: a simple Why/Why Not argument should suffice for this one:

Why Allow Windowed-mode:

It’s more convenient for your users. Some users multitask (gasp!), even while playing games. This is much harder to do when your game is Fullscreen. I suspect this is a part of why games like Minesweeper and Solitaire get so much play-time. They’re built into the OS, sure, but you can also fire them up and play while you’re waiting for something to download/compile/whatever. Very handy!

It’s more convenient for you. Debugging is hard, and debugging fullscreen is harder! My own game engine (in debug builds) has a feature to throw a debugging/log window up so I can watch internal game messages etc: you can’t do this if your game is always fullscreen. Not only that, but if your game crashes at some Direct3D stuff (which can happen in early builds, before you lock down your video interface code), it’s very tricky to find a cause when you’re staring at a blank screen. A blank window on the desktop gives you more context and options.

It makes paying certain Windows taxes more obvious. If you’re running in Windowed mode while developing, you’re going to be hitting the titlebar close button, you’ll be minimising/maximising your game Window, or maybe just clicking other apps, stealing your game’s focus. Because you’re doing these things, you’re much more likely to take the time to ensure your game handles them correctly. Fullscreen games are required to handle these situations too, you know: but some of them never get around to it! (Civilization 3, which is always “fullscreen”, can experience a rather ugly crash if I dare to click something on my second monitor while I’m playing).

It’s future proof. You might think your fullscreen game is pretty cool, what with it supporting resolutions right up to 1920×1080, but who knows what the future holds? How well will your fullscreen game look on some giant desktop running 12,000×12,000 pixels? Or do you just expect no one will be playing it then? (if you don’t, then code this way: you’re sure to be correct). Windowed mode doesn’t solve this completely, but it gives your users more options.

Ok, hopefully you can that there are always scenarios where that option would be valuable, but you might not be convinced to allow it in your game. Let’s take a look at some reasons why not:

Why NOT allow Windowed-mode:

It’s hard to code. Oh no, now all of your video code has two scenarios to account for! Well, actually, no it doesn’t. Once you’ve initialised Direct3D correctly, none of your other code even needs to *know* it’s drawing to a windowed area of the desktop. And initialising Direct3D to support either Windowed or Fullscreen mode is easy! I’ll bet you $5 that the sum total of video code required to support this option is LESS than the amount of code required to present the option to the user and store the result.

Fullscreen is more atmospheric. Atmosphere is important in my game! By all means then, make fullscreen the default. Plenty of games do. I’m just asking for the option!

But I want to retain control. Fuck off! The user is in control: it’s their computer. Besides, if the user really wants to window you, they can do it: they can fire up a virtual machine and lock you inside it: good luck getting into fullscreen mode then. Of course, if it’s that important to them, they’re more likely to just uninstall you and go play something with a windowed option.

And there you have it. Why I believe every game should support Windowed-mode!

2009
11.11

In Windows (like every operating system), when you’re writing an application or game there are certain things that your application is responsible for handling: some of them are easy, some of them take a little bit more effort. On his excellent blog, Microsoft’s Raymond Chen calls these responsibilities “Taxes”, and there are good reasons why you should pay them. Windows taxes include things like:

  • Respond to Windows messages correctly
  • Respect user action (don’t silently cancel a Sleep request)
  • Non-standard installs (don’t assume C:\Windows!)
  • Run fine as a Standard User
  • Respect the user’s settings

Raymond talks about more complex taxes too (internationalisation, heirarchical file systems), but I’m sticking to what I’m comfortable with!

Unfortunately, amongst all applications, games appear to be the worst at being good Windows citizens, there are far too many games out there (not just freeware ones either) that don’t pay any of the above taxes, and (to sustain the metaphor) some start trying ‘tax-fraud’ schemes like:

  • Trying to disable Alt-Tab
  • Refusing to be minimised (automatically restoring themselves after 1 sec)
  • Preventing the system from shutting down

I might make this another series because there’s plenty to talk about, and most of it’s not even that difficult these days: you just have to be aware of the situation, and what the correct behaviour is. (I must admit I never gave thought to multi-monitor situations before I got my second monitor).

For now though, I will limit myself to a list of ten ‘golden rules’ which I believe all games should obey, at a minimum (not all of them are Windows taxes – some of them are just treating your users properly). In fact I will expand on some of these in later posts too, because they’re worth talking about.

Top ten Golden rules for Games: being a good Windows application

  1. 1. Fullscreen games: always allow an option to run in a Window.
  2. 2. Provide gamma and volume controls, and separate music from sound.
  3. 3. Always allow your game to be paused, saved and quit. At any time.
  4. 4. Provide a way to skip anything non-interactive: from cutscenes to credits.
  5. 5. Respect multi-monitor: If you were dragged to monitor 2, next time open on monitor 2.
  6. 6. Respect the filesystem: don’t open files in Read/Write mode if you only want to read from them.
  7. 7. Respect security: A game does not need an Administrator account to play!
  8. 8. Respect UI settings: if the user has selected ‘Use Large Fonts’ in Windows, use larger fonts in your game!
  9. 9. Respect sessions: if the user logs off/hibernates/shuts down, handle it gracefully. Don’t try to block the action, and don’t lose their progress.
  10. 10. Adapt to a changing system: if you last opened on 1680×1050, but the system now says the monitor can’t support that, open in a res it can support.

I’ll talk about how to implement some of these (and why they’re so important) in future posts.

2009
11.09

Class Balance

Class balance. In the RPG sense, class balance means that the various different character types (wizard, warrior, druid etc) are “balanced” in the sense that the difficulty of the game, and your character’s ability, remain approximately the same regardless of your choice of class. (and Race: Humans, Elf, Dwarf etc)

Obviously, in an online-, or otherwise multiplayer game, class balance is critically important. If your wizards can always beat your warriors, the game will NOT be fun for people who choose to play warriors. And they won’t switch and play wizards, either: they’ll just stop playing and find another game.

But is class balance critical in a single-player game, like Icefall? In many roguelikes, the classes aren’t balanced: some classes and races are substantially more powerful than others (e.g. High Elves might come complete with bonuses to all their stats, Resist Poison, etc etc – with no downsides), and players are actively encouraged to start with the easier classes.

A third alternative is to balance classes not for ‘difficulty’, but for ‘effort’: you might be free to roll a powerful Immortal instead of a lowly Human, but the Immortal will require twice as much experience to gain every level.

I’m not at the stage of class balancing yet – but I’m thinking about it.

2009
11.05

What’s a reasonable minimum spec to aim for these days?

With Icefall, I’ve already taken the decision to target Direct3D9 – I get a lot of extra capabilities compared to DirectX8, and it still works with Windows XP unlike 10 or 11… a pretty simple decision.

But what about in terms of video memory? And system RAM? What’s a realistic minimum these days? Icefall is a freeware, turn-based RPG, so by rights it shouldn’t require a leading edge PC, but I need a specific target to prevent limiting myself unnescessarily.

Howzabout 32mb video, and 512mb RAM? I think that fits most every PC you could buy in the last few years… and should be enough for some reasonable effects. Anyone got any thoughts on this?

2009
11.02

Should Icefall come with an Installer/Setup program?

My previous games (like the Five Hundred card game) didn’t require any installation at all: it assumed you had DirectX7 (the game just failed if you didn’t), and all of the files it needed were in the same directory as the EXE itself. You just unzipped it to wherever you liked, and double clicked the EXE to play. To uninstall, you just delete the folder.

Icefall is a little bit more complicated. All of the game’s data is still a relative path from the EXE itself, but this time it needs a specific Direct3D9 library installed (one that doesn’t ship by default with the rest of DirectX, but that other games may have already installed). So I need to include the DX Installer.

The Microsoft DX installer is smart enough to not overwrite a newer version of the same library (and you can only include the needed library – I don’t have to include the full DX9 100mb installer!), so I don’t need to worry about that stuff, but the question is, should I include this as an ‘optional’ installer that the user can run if Icefall doesn’t run immediately, or would it be less confusing to just make a full install program that all users run, and call this as a part of it (I could throw out options for the Start Menu etc. at the same time).

I’m leaning towards making a full installer, mainly because the DirectX library is designed to never be uninstalled (it’s a shared library, and other D3D9 apps might use it), and it would be very confusing for users to have an installer with no corresponding uninstaller… also, I may as well get with the program and use the Start Menu, registry etc. the way Windows programs are supposed to. Does anyone have any opinions on this?

Bonus trivia: I get quite regular emails about my Five Hundred game, since it made it onto lots of the large ‘freeware games’ websites and was quite well received at the time. One of the common questions people ask these days is “how do I uninstall it? It’s not in Add/Remove programs”. They must have forgotten that they never installed it in the first place, just unzipped. A few of them are still confused when I tell them to just delete it, so it’s clearly not what today’s users are expecting.