Thursday, 12 June 2008

Stealing Ideas from other sources...

One of the most ironic things I find about writing a Roguelike game is that the ideas for additional content never seem to stop bubbling to the surface. And that, when analysed, most of these ideas come from either other RLs, CRPGs or (especially) MMORPGs.

For example, instead of coding, I've been playing (and dying mainly) a lot of Sangband recently, and I've realised that the lack of character classes is an inspired design choice. Much has been written about classes in Roguelikes, and eventually, perhaps, I will also want to take Kharne into a classless direction. Classes are, on one hand, convenient labels/stereotypes for a character and on the other, a restrictive straightjacket preventing the character from achieving his or her true worth.

Another idea which I think might prove to add another facet to gameplay in Kharne is Reputation, which in a World of Warcraft context is:

You can gain or lose favor, otherwise known as Reputation, with many of the several different factions in Azeroth by completing certain quests or killing certain creatures. Doing so will usually unlock special rewards or new quests to accomplish.

My only concern with implementing reputation is that it can turn into a mascochistic grind very easily - there are majoring game-play balancing issues to be considered (much like Pudding Farming in fact), but a synergistic reputation system that minimises repetitiveness could add much to a RL.

Another idea, currently being discussed on r.g.r.d is that of Dungeon Morphing, dynamically changing the dungeon either independent of the player or as a response to the player's actions. Where I think this could be extremely interesting is implementing timed levels that require the player to do something in a certain period of time or else face near- or certain doom. Like in Oblivion for example.

Leaving all this side, on the development front, my current task is finishing the monster implementation, which I need to do before I can progress magic further. One of the decisions I made early in the design process has come back to bit me slightly. I've made great play (here on this blog and elsewhere) of the fact that our brave little @ is just another creature. But why does a rat, for example, need to receive the same treatment as our @ in terms of having an inventory and suchlike? And do rats really need to have Charisma stats as well as Armour and Evasion?

Thursday, 5 June 2008

Progress Report #5

Slowly but surely, things are coming together. Here is a sneak preview of the new spellcasting screen:

For the sake of tradition, and ease of implementation, I've decided to forsake originality and go for the spell book approach found in many other roguelikes. There are fifteen possible schools of magic, grouped thematically, with eight spells in each. I'm also implementing basic metamagic feats, to allow a bit more flexibility with spellcasting.

In the above screenshot, our '@' has access to five schools of magic, and in the she can cast four spells from the Tome of Aether (air/wind flavoured spells) with varying degrees of probability of success and mana cost (which in turn are calculated from various stats and skills). Eventually, I hope to add some sort of miscast/mutation mechanism.

Current plans are to finish implementing at least the basic schools of magic, then start work on the monsters and serialisation. Then Kharne should see an official (v0.1) release.

Wednesday, 4 June 2008

The Psychology of Getting Things Done

Andrew Doull over at ASCII Dreams has a screamingly relevant (to me) post up entitled The Cost of Interruption describing the travails that Roguelike Developers are going through. I must admit part of the reason I've slowed down coding on Kharne over the last couple of weeks is the same as his:

"...With coding, if I have a longer period of time, I'm more productive. Not as in twice as productive, but probably ten times or more...The reason for this is the time required to rebuild the mental model of the program before I can generate new, productive code. This mental model doesn't have to be complete, but it does have to be correct, and I've inadvertently introduced logic bugs that have persisted for years, due to faulty assumptions about how a particular section of code works..."

"...So rather than plain procrastination, blogging and gaming has become activities where I feel productive in a short term without experiencing this mind numbing interruption cost - the interruption cost of a blog entry is just re-reading the entry I've written so far, which is a much lower barrier."

I've experienced this succinctly in the last couple of days. Monday evening I was able to get a great deal of code written for the Magic-Handling GUI Interface in a good solid 2-hour stretch of coding, yet last night, when I finally managed to get round to doing some coding after spending most of the evening do something else (equally mentally draining as coding), I found I had great difficulty in doing even the simplest of functions (I was trying to write the routines to calculate the mana cost and spellcasting success probability of spells). In the end, I gave up and went to bed.

Its not quite got to the stage that Andrew describes though:

"...It has got so bad recently that I've started dreading coding, in so far as the idea of doing something half-way and getting interrupted is a feeling I don't particularly want to experience."

It also doesn't help that my s.o. is suffering from a bad flu at the moment and is thus spending most of her time playing Age of Conan, and seeing her play it nibbles slightly at the edges of my own MMO-addiction.

Thoughts on Serialisation

I'm finding out that implementing Serialisation (i.e. writing the state of the game out to disk) is a pain. Not only because pre .NET Delphi (I'm using Delphi 7) doesn't support inherent serialisation natively, in the way Java does, but because it requires a great deal of clarity of thought when it comes to designing and writing data structures and classes with serialisation in mind.

Let's look at what serialisation is required for Kharne:
  • Storing '@' information, such as current location, stats, inventory and current effects that he/she(/it) is subject to. The player is represented by a specific instance of the TCreature Class.
  • Storing the dungeon information. Ironically, I'm finding that this is the simplest to serialise, since the Dungeon class (cunningly called TDungeon) is basically just a multi-dimensional array of integers and booleans.
  • Storing the monster information. Monsters (also instances of the TCreature class) are stored in a TObjectList, and there are soft references to them in the dungeon class (by soft, I mean absolute ID addressing, not pointer referencing).
  • Storing the item information. Items are stored in a TObjectList, and there are soft references to them in the dungeon class. However, there is an added difficulty in that Items themselves are effectively compound objects (consisting of a base TItem and optionally one or more TItemEnchantment classes to represent magical properties of the item).
  • Storing the high-score table and any bones files.

The old Kharne did all this successfully enough, but with one major drawback: the save files lacked any soft of compression and were stupidly big (20 Mb!). This was due to the crude method I previously used for handling saves files (basically, standard Pascal WriteLn/ReadLn). This bloat is unacceptable however in the new Kharne. Fortunately, if I switch to using a more modern implementation, i.e. streaming (which Delphi supports extremely well using both TFileStream and TMemoryStream) and also use one of the many compression libraries, the save files can be reduced to an acceptible size.

Now, there are plug-in Delphi libraries available that implement serialisation but I'm not convinced that using them would be any easier than using the above methodology. I will have to do further investigation on these.