Uploaded the newest code

Tuesday, May 13th, 2008

I noticed today that my game was broken, I’d uploaded new code, but hadn’t re-initialised the database.

This appears to be an issue with Google App Engine, changing the database is not trivial.  While at the Guardian we not only wrote a cool system for managing database changes, we open-sourced it (or some of our contractors did).  But Googles Bigtable implementation would be difficult to adapt to dbdeploy.

Anyway, I fixed a few bugs in the code, and re-uploaded, so all of your accounts are gone, but I’ve recreated everything, so you can go and create a new account and play again
Features added include

  • Hunting now searches for a critter and starts a fight.  Your health is not saved, and you can’t die, but it shows the initial fighting implementation.
  • Moving now costs a movement point, and you can run out of action points, which are regenerated at a rate of 1 every 30 minutes
  • Map is rewritten again, you now have a list of visited areas, so you only see areas you’ve previously explored

Hints about what to do next would be nice, I think the basic things include:

  • Better fighting, with saved health etc.
  • Searching for interesting items / looting bodies
  • Inventory
  • Dungeons / Areas of interest
  • A Town or Village for trading, resting etc.
  • Travel between zones

WebMMO - Some critters added

Wednesday, April 16th, 2008

Just a couple of updates to WebMMO

  • I’ve made the map bigger.  Not for any good reason, just it just suddenly felt too small.
  • I’ve added a Hunt facility on the left.  It simply looks up in the database an appropriate monster to fight you.  In zone 1, there is a big dog, and a yappy dog that are found in sand and grass.  But the sand lizard and grass lizard are only found on their respective tiles.
  • I’ve added some admin pages to allow the initialisation of the creature database.

My todo list is longer than ever.  I’m thinking combat or action points is definately the next thing to attempt. Code is uploaded as always, please feel free to criticise, I’d love to get some opinions of a better way of defining the monsters / items and stuff rather than the dictionary in data.py and then turning that into actual dbObjects and putting them.

I’ve tried using the data import tool, but it’s quite complicated as to how you do so, and the documentation sucks, so for the moment I’ve given up.  Maybe I’ll create an admin view that lets you upload a CSV or something and then it wont be hard coded in the application.

Efficiency is not the primary target right now, just getting to having something working is target number 1, but I think the model I’ve got seems to work.

Web MMO - Designing an RPG

Tuesday, April 15th, 2008

So my setting is decided, and the game is going to be a classical RPG style game.

So the design of the game is based around the user experience of starting a new character, exploring a new area and fighting creatures. Other ancillary activities will include inventory management, item trading and inter character fighting.

So we are going to need some way of representing how good our characters are at various activities. Now dipping into real RPG design there are various thoughts on ways of doing this.

Advancement

Most peoples role playing heritage can be traced directly back to Dungeons and Dragons, which provides a levelled class based system. For example a level 5 mage is more powerful than a level 3 mage, and only cleric classes can cast priestly magic, mages can’t use armour and so forth.

In many games, and gaming systems this is the default way of thinking about character definition and character advancement. In these games, your characters power and skills are directly tied to their “level”, and this can cause problems, with level 10 characters being able to withstand many more solid hits than a low level character.
Other RPG systems completely abandon a class system. Warhammer RPG is one, you pick a profession, and at various points you can advance in your profession, gaining a small bonus to your statistic block, and opening up new careers to you. An older, more powerful adventurer has more resources, may have better skills, but they’re raw health is exactly the same.

Personally because of the realism I prefer the idea of skills improving, but not your raw health or main attributes, so I think we’ll go with that kind of advancement system.  Remember that in most games, you are looking for the system that enables the most fun.
Stat Blocks

I tried to look around the internet for a comparison of various role playing statistic / skill systems but couldn’t find anything appropriate, so I’ll have to sum up from my knowledge of a couple of systems.

The DnD way of describing a characters attributes is to have Strength, Dexterity, Constitution, Intelligence, Wisdom and Charisma. This system or something like has been used over an over, and many people are familiar with it. It provides two sets of statistics, Physical stats, Str, Dex and Con, and the Intellectual stats, Int, Wis and Cha. You may have played computer games with those statistics blocks, or you may have played with similar systems (Endurance replacing Con for example).

The White Wolf games, Vampire: The Gathering has a system that contains nine attributes (or Traits), rated between 1 and 5, and separated into 3 groups. Physical stats, (Strength, Dexterity, Stamina), Mental stats (Perception, Intelligence, Wits) and Social stats (Appearance, Manipulation, Charisma). Character generation allows you to assign 7, 5 and 3 points to each stat group, and assign them between the stats within the group freely.

The Warhammer RPG had a stats block, that covered a number of statistics, some of which could be described as skills in other systems. Each player had WS (Weapon Skill), BS (Bow Skill), S (Strength), T (Toughness), Ag (Dexterity), Int(Initative), WP (Will Power), Fel (Fellowship), A (Attacks), W (Wounds), SB, TB, M (Move), Mag, IP, FP. (I Cant find a reference and my rulebook is packed up in a box, so I can’t remember what they all mean).

So there is a number of ways of representing the core statistics. In general Tabletop RPG’s have stuck with just a few statistics, as that saves on complex calculations at the table. Computers have ported Tabletop rules, but haven’t generally added the complexity that computers could do. There could be two reasons for this,

  1. Players want to be able to see their statistics, and lots of pages of stats makes them unsure how to min/max decisions about armour, weapons or skill increases.
  2. Designers can’t effectively balance a system that contains lots of attributes, the formulas gets too complicated to balance easily.

Skill Systems

There are various ways of representing the skills and knowledge of the characters. The Warhammer way says that all actual tasks are run from those 16 attributes. Nothing else is needed.

Original DnD didn’t have skills, 2nd edition added Proficiencies, and 3rd edition added feats and skills. Each consumes a skill slot and is just usable, and associated with a statistic.

Vampire: The Masquerade has a defined set of around 35 skills, each valued at between 0 and 5, including skills like Handguns, Drive, Occult, Dodge, First Aid etc.

Diablo and some other Computer RPG’s have a skill tree, with learning the first skill enabling the next couple.

I hope this has covered some of the many ways in which it could be possible to describe a character.  Really when you get down to it, describing what the character can do is pretty fundemental to a computer role playing game.  With a human games master, they can make a judgement call, like “Well you have a high dex, and you come from a human settlement that has horses, I’d guess you can ride a horse pretty well, and even manage to jump on or off a moving horse, but nothing fancier”.  The computer can’t do that, so a more complicated system will come out.

For our game, given that it is only a prototype and I’d rather be programming and getting something working than trying to come up with the best ever design, so I’m going with the following decision as I think they will be simplest to implement

  • Attributes: 3 Physical (Strength, Agility, Endurance), 3 Mental (Perception, Intelligence, Social)
  • Advancement is via skills only
  • Skills: Combat (Clubs, Blades, Bows, Dodge), Environment (Hunting, Hiding, Tracking).
  • Magic: Nothing at this time, maybe later

Web MMO - New Version

Monday, April 14th, 2008

So I’ve been doing this for almost a week, and I’ve got another version up at shipwreck.mibgames.co.uk.  It’s still not really playable, there’s certainly not a game there yet, but it’s a lot better than it was.

  • Now when you create a character, you get the generic stats, and can’t edit them
  • Your characters location is randomly set to be a beach location along the north coast of the island at creation
  • You can now see a map of the areas around your character (using some free graphics I found online and threw together in 5 minutes, hence the mismatched sizes)
  • You can click on a map location to travel there, assuming that it’s possible (you can’t walk on the sea)
  • All new code uploaded to the google code project

So, I’m feeling slightly proud, or was until I started writing my todo list, here’s the main features waiting to be done

  • Character creation should be fleshed out, choose a profession
  • Action points based on time, and moving around the map should cost action points
  • See other characters on the map, and send them messages
  • Character advancement commands - (learn skills, practice skills)
  • Items - Allow items to be found, and picked up
  • Monsters - Allow monsters to be met and fought.
  • Interzone travel - Currently you can’t travel from zone 1 to zone 2, this should be fixed.
  • Finish drawing the map, my laptop power ran out last night, and the mpa was only half started.
  • Better / More graphics, including Terrain tiles, characters, monsters

Phew!

You’ll also notice if you look at the code that there are no tests anywhere.  This is against my normal coding practice, but the django test suite refuses to work under AppEngine (the database layer is required to run the django tests) and I haven’t got around to writing proper tests for anything yet.  The key classes to write tests for are the helpers.  That would probably also help me split a lot of code out from the views and into more helper style methods.

AppEngine update

Thursday, April 10th, 2008

So my host just started working this morning, so you can see the first stab at the app at http://shipwreck.mibgames.co.uk

I still haven’t quite got the hang of the developer accounts, but I’m persevering with my gmail account, although I would have liked a way to subscribe to the google group with my mibgames account, as I actually read that one daily, whereas gmail I don’t normally make a habit of reading. Although I’ve also apparently managed to get duplicate emails being sent to my personal email address, but haven’t worked out why yet. I’m sure I’ll work it out.

[Edit: Found out why, I had setup my personal account to download email from my gmail account via POP3 ages ago and hadn't turned it off.]

I also had my first couple of weird issues. I had created a django template, called base.html, which defined the base layout (or will do eventually), and was creating a template called create_character.html which inherited from the base template. I defined my title and main blocks in my template, and filled them in, and when I hit the template I got the weird error, TemplateSyntaxError that appeared to say that {% block main %} had a syntax error, and that it couldn’t read the expected next character.

I scratched my head a bit, tried renaming the blocks, tried rewriting it, to make sure I hadn’t done something really stupid. Eventually, I moved the blocks around, moving the title block to the end, and the main block to before the title, and it suddenly started working. Changing it back now doesn’t break it anymore, so I’ve no idea what caused it. Very weird.

My second issue is to do with getting stuff out of the BigTable, but first I had to get something in, and this is where I met my second favourite feature so far. I created a model for the player’s character, containing some basic stats, skills, and admin values. Having created the model, I want to try to be able to create one, save it to the BigTable, and then get it out again.

But the easiest way of creating a character without needing to generate random numbers, and do weird things, is to create a form with all of the relevant fields, and I can manually enter the values, press save and voila, it would save. So I set about creating a Django form for my model object. Having entered the 17 lines of attributes, run a few vim commands to replace db.StringProperty with forms.CharField and stuff, I thought, there must be an easier way than this.

And there is, in google.appengine.ext.db there is a module called djangoforms. Instead of my 17 lines of code, and the hiddeous thought of writing some manual code to hookup the form.clean_data['strength'] to character.strength, you can instead use the following lines of code

from google.appengine.ext.db import djangoforms

class CreateCharacterForm(djangoforms.ModelForm):
class Meta:
model = Character
exclude = ['location', 'health', 'armour', 'owner']

Yup, thats it, create a djangoforms.ModelForm, and give it a Meta class that specifies which model object you want it to associate with, and it does. In your view you just do

form = CreateCharacterForm(request.POST)
form.save()

and it does… unless you’ve declared anything as required, and excluded it from the form at the same time. Trying to wrok out how to get access to the model object, set it’s owner value before saving it was quite hard, until I noticed a parameter on the save method, commit=True. Checking out the source, it seemed true, if you give the keyword parameter commit and set it to False, the form.save method simply sets up your model object, fills it from the form and returns it to you, unsaved. I can then do

character = form.save(commit=False)
character.owner = users.get_current_user()
character.put()

And bobs your transvestite uncle who keeps turning up to family gatherings even though nobody has invited him.

My only problem now is that having executed this once, the object should exist and be in the datastore. But my code to get it back out, doesn’t seem to work.

I’m probably doing something really stupid, but from what I can read from the docs, this code should work.

character = Character.all().filter('owner=', users.get_current_user()).fetch(1)

I’ll work on it tomorrow and see what I can get working then.

Oh last feature, and this is my favourite feature so far. While looking to try to work out if my data was in the datastore, I found the dev_appserver admin interface. It doesn’t provide you with the logs, CPU cycles used or bandwidth obviously, but it does provide the facility to dynamically examine the datastore, and an interactive python interpreter, so you can just import your model and execute query methods to your hearts content.