Thursday, February 23, 2012

Lair Combat and Henchmen

Avaloria is a world full of bonuses. Bonuses from armor, weapons, structures you build, your lair itself. They come from everywhere. Lately I have begun work on the lair level system and henchmen. These are the last two 'must have' systems before I let people play test. Just about everything else is up, running and working well. This mechanic is going to be one of the many game defining things for Avaloria. Instead of flat out pvp (which may or may not be added, still undecided if I want that or not), the goal of players will be to build up their lair to the point that they attract followers or as they are called in the code: henchmen. Henchmen come in all different shapes and sizes and live inside the lair. You, the player, will have the ability to direct them to do your bidding.

This becomes interesting when you allow said henchmen to go out and wreak havoc upon opposing deity-factions. This mostly goes hand in hand with the Lair leveling system, which in turn ties into the structure building system. Currently as it stands, when you dump gold into building a structure, that gold is also dumped into your lair as currency for leveling. When your lair levels it gains stats, just as the player does when they level which are used when henchmen from opposing lairs come to attack your lair. Depending on the structures you have built, the bonuses given to your lair, and you as a player will differ. Some buildings buff different stats, while others generate gold for you, or attract followers.

On the backend, henchmen are nothing more than a small dictionary with some stats used for battles and the amount currently stationed at your lair. This allows for a pretty flexible system that makes it rather trivial to add new types of henchmen. Eventually you will be able to raise resources (undetermined what that will be, but the mechanism will be used to limit the amount of times you may initiate combat with another lair) to then lead your army to an opposing deity-factions lair and begin a siege. Sieges can last minutes or hours depending on the parties involved. If you are the attacker and you manage to breach the Throne Room of the opposing player you will receive rewards (Experience, loot, some of their gold, and most likely a large amount of fame based on the level of the opposing player.).

Eventually henchmen will have their own sets of skills and uses for things other than just lair combat. Maybe you will set them loose on a opposing faction's zone/town. Perhaps you will use them to gather materials needed for your next siege? The choices will be close to endless once the system is in place. There is still however quite a bit of code that needs to be written before we get there.

Tuesday, February 14, 2012

Skill System Refactor (Or The Wild world of Percentages)

I don't even know if I can really call it refactoring, since I am really just changing the way skills advance and the currency used for said advancement. However, it is quite a drastic change on the backend.

Previously I had thought that I would make the players seek out trainers and spend their gold on ranking up their skills, which would be found randomly through questing/as loot etc. This seemed like a good idea until it came time to actually advance the skill. What got modified? If it's a damage skill, it seems silly to change the base damage dice every single level. Not scalable. Then, I briefly entertained not making every rank do something in terms of skill effectiveness. That seemed like a cheat and a waste when I thought about it from the player perspective. All in all the system based around gold spending and trainer finding just seemed far to cumbersome, to me as a developer and a player.

So I implemented something that harkens back to my days of playing the fabulous MMORPG Asheron's Call. In that particular game, you spent your accrued Experience Points on your attributes and skills. This is obviously a VERY open system, and is designed to be as such. However, Avaloria aims to be very open in terms of character development. You CAN wear plate armor and cast spells. You may fail a slight bit more than others, or possibly have some spell backlash due to the metal armor, but that chance will be small if you specialize into a class designed for battle magic use. Classes will never be mandatory, and most skills will be available to all classes/non-classed characters.

To that end, skills now have a backend component that is merely a floating number which starts at .01. Each point added to the skill (using Experience Currency) will relate on the backend to a 1% increase to the skill's rank modifier. This rank modifier is then used to increase/decrease certain things pertaining to the specific skill.

So, for example the Strike skill. This is a medium damage melee strike. The modifier for it increases damage output, and also slightly increases critical hit chance. I also have a 'Toughness' Skill that adds to constitution and therefore gives the character more health. In that skill's case it's modifier relates to how much of a bonus the character receives.

This system is quite extensible and can be limited/used in many different ways. I look forward to implementing more skills and spells. Now that most of the backend i wanted up for an alpha is complete, I will actually be able to work on game content.

Thursday, February 2, 2012

Refactor all things!

When I began this project almost a year ago, I had never written anything larger then a couple 100 lines in python. My main experience with django was with a small app I wrote for work to scrape emails for a particular failure case we had. Nothing I had done really quite prepared me for attempting to assemble all the game systems needed for a robust, state of the art, and more importantly; modern mud. This is evident in the code I wrote at that time, and so I have spent the past few days combing through it all and re-factoring the horrible parts, taking note from the clean, well designed parts.

This brings me to the next topic: How to make a huge, giant, game world tick without destroying the computer running it. Thankfully with the help of the Evennia devs, the solution is almost so simple it hurts to think I didnt realize it on my own, but you live and you learn.

The method is what is called a 'global tick' or 'global runner' system, and within Evennia at least, it is very easy. Just take a look at the following code:


class MobRunner(Script):
"""
Controls when the update functions for mobs are called. Holds
a list of dbref's for subscribing objects (Mobs)
"""

def at_script_creation(self):
self.key = 'mob_runner'
self.interval = 30
self.persistent = True
self.desc = 'controls the subscribing mobs'
self.db.mobs = []

def at_start(self):
self.ndb.mobs = [ search.objects(dbref) for dbref in self.db.mobs ]

def at_repeat(self):
self.ndb.mobs = search.objects('mob_runner')
[mob.update() for mob in self.ndb.mobs if mob.db.should_update ]

def at_stop(self):
self.db.mobs = [mob.dbref for mob in self.ndb.mobs]


So what is that doing? It's basically keeping a list full of subscribing object id's. On start it reads these into memory (say after a server restart), then when the script rolls around and repeats it does two things: update the memory stored list of mobs subscribing to it, and then running the update function on each subscriber, if it is set to update. This particular script runs every 30 seconds and is what controls a lot of random upkeep for the mobs in Avaloria. This approach can be used with multiple scenarios where EVERYTHING in the world needs to have something done to it. The resource usage is minimal and everything runs fantastically so far, even when jammed full of objects all needing updates.

Thanks to the guys at the Evennia project for setting me straight and not allowing me to run my server to an early grave :)