Object Oriented Programming (OOP) is one of the programming concepts that can cause people a lot of pain. The biggest problem is in the way it is taught. We learn about a parent class, such as Animal, and inherit some child classes, like Dog, Cat, Bird, and Fish. Then we create methods like move() and call() and implement them in the child classes. After creating a beautiful design, any student will wonder what the point is.
The most common example of practical OOP programming is GUI (graphical user interface) libraries. You have the ability to have a consistent set of base classes that you modify to create customized forms, menus, etc. You can look at gtkmm (gtkmm - the C++ interface to GTK+) for an example.
Most GUI libraries are already well designed, and massive. As a result, we'll look at the design of a slightly smaller program. We'll work on designing a slightly smaller program. I'm not going to create code, just the design that could be implemented in many OOP languages. C++, Java, C# or VB should all work to implement it.
Our problem will involve making a character creation program for GURPS. GURPS is a roleplaying game where you create a character and then let someone else come up with ways to make his/her life difficult. If you go to GURPS Lite you can download a summary of the rules and get an idea of what a character sheet looks like. It is basically the list of "interesting" things about your character. There is also a program for creating GURPS Character Sheets at GURPS Character Sheet.
One of the things that can cause people to avoid GURPS and play other systems, such as Dungeons & Dragons, is the fact that character creation can get... complicated. This is precisely why it is useful to have a program that will do all the calculations for us. Did I mention it's complicated? Yeah, well it's complicated enough that the makers of GURPS don't have the best character creation program. Go with the open source one linked above.
We will look at how classes can be combined, inherited, etc to create an OOP program that manages the process of creating a character sheet. In GURPS, characters are represented by a collection of attributes, advantages, disadvantages, skills, and languages. In addition, a character can have possessions. Ideally, a character should also have a brief description and references to non-game things such as height, weight, hair color, etc. You can see a sample sheet on page 5 of GURPS Lite.
The short version, if you haven't read the PDF yet, is that you build a character with points. 50-100 points is a common level. "Normal" people are 0-25. Good things, such as skills and advantages are positive points. Bad things, mainly disadvantages are negative points. Attributes can be bought up (costing points) or down (giving points). If you haven't read GURPS Lite yet, go read it. It'll make the rest of this tutorial make a LOT more sense.
At this point, I'm going to start investigating the various aspects of this problem. Rather than commit to a particular design, we're going to analyze the requirements. One of the biggest mistakes you can make in any program design is committing to one idea too early. Our goal will be to carefully build up requirements, then design a program that fills them.
Let's start with attributes in our exploration of design requirements. Fortunately, they are pretty easy; increasing or decreasing them can be viewed as simply purchasing an advantage/disadvantage. These advantages can be purchased in multiples. +3 strength is the same as three levels of +1 strength. Since many advantages can be purchased in levels, we'll need to account for this.
In general, advantages are not as simple as just purchasing them. Advantages can be modified by enhancements and limitations (you have to buy the books to learn about this). These increase or decrease the cost of an advantage by a certain percentage.
Disadvantages are very similar, including having enhancements and limitations. Most games limit the number of points of disadvantages that you're allowed to take for a single character. This is to keep you from creating a psychotically powerful vegetable. Being able to destroy the earth is neat, but when you're only awake once every ten years and suffer from paranoid schizophrenia while you're awake, it isn't very fun to play.
Advantages and disadvantages can do a wide variety of things. One thing, obviously, is to modify the attributes. They can also provide new abilities (like breathing fire for dragons, or retractable adamantium claws for cool super heroes). They can also gives skill bonuses or define a race.
For example, being a dragon is an advantage (see the breathing fire above). Usually, being a member of a race is represented by a collection of advantages, disadvantages, and skills. The combination of these defines a meta-advantage called a racial package. A racial package is considered a single advantage or disadvantage, regardless of the number of component advantages/disadvantages in it.
Skills all work on a level system. Skills are defined based on their difficulty and the attribute they're based on. Programming is an IQ hard, while hiking is HT average. Some skills depend on the technology level of the setting. Being a physician in the 1700s meant deciding how many leeches to attach. Being a physician in 2009 involves MRIs and other gadgets. Finally, some skills have defaults. Even if you never learned how to ride a horse or drive a car, you can give it a try and might succeed.
Skills can also have specializations (such as Applied Math, Pure Math, Statistics, and Cryptology). These are areas of expertise within a broad skill that may or may not be optional. Work within a specialization is easier, while work outside it is harder. Some skills, especially karate and judo, also have techniques that are advanced maneuvers. They are normally performed at a penalty, but can be bought up more cheaply than the entire skill. This can make a karate master who specializes in spin kicks, for example.
Some settings allow magic. The default version of magic uses spells as skills, where each spell can have prerequisite spells or abilities. Psionics is another feature of some settings, which uses a mixture of skills and advantages to represent it. Got it so far? Good.
Finally, remember that there are various additional books available. GURPS Basic Set Characters lists almost everything you could want (including equipment) to build a character in almost any setting, from gritty cyberpunk to swords and sorcery to a modern detective story.
Sometimes, however, you just need a few more details. GURPS Magic adds MORE spells, including spells for powering your computer during a power failure. Powers gives you more rules on how to use the advantages, disadvantages, enhancements, and limitations to create super-heroes and robots. To help you out, a few extras are addedThaumatology talks about completely different ways to handle magic (including a system similar to the Dungeons & Dragons one). The list of the things you can buy takes 10 pages in the Basic Set. We will NOT want to hard code that list.
At this point, the scope of the problem should be fairly clear. We're talking about a program that is sold for $14.99. So, the question becomes, how are we going to implement all this? This is the type of problem people pay for, so this is the type of problem we want to be able to design solutions for. If you are not familiar with object-oriented programming, this problem is likely to look like a nightmare.
An objected oriented design will help keep this whole thing manageable. The most fundamental class is going to be... the character. Basic information that needs to be recorded with a character: Name, player, height, weight, size modifier (a measure of how extremely large/small the character is), age, appearance, point total, and unspent points. Most of these are strictly optional. Primary attributes are ST (strength), DX (dexterity), IQ (intelligence), and HT (health), while secondary attributes are HP (hit points), Will (willpower), Per (perception), and FP (fatigue points). Basic Lift, thrust and swing damage, basic speed, basic move, and encumbrance round out the attributes.
Other summary data that's useful to have: Languages (including whether or not the character is literate in each one), tech level, cultural familiarities, reaction modifiers based on appearance, status, and reputation, and dodge, parry, and block (for a fight). These are all going to be calculated from what comes next. A list of advantages, a list of disadvantages, a list of skills, and a list of equipment. Finally, it's good to have some notes about the character, such as background info and how all of the above fits into a coherent whole.
Stop and think about what we have to have to represent all this data. Keep in mind that HP (hit points) will need an overall value and a current value! The same is true of FP (fatigue points). We will need to keep track of the equipment that is actually being carried (for encumbrance) compared to equipment that is simply owned (such as a house). We will even need to pay attention to things like backpacks, which have a limited capacity (no carrying 50 potions of healing, 12 swords, 30 throwing knives, 3 maces, 2 clubs, and a partridge in a pear tree!).
Most of this can be simply represented with a few data fields. However, pay attention to the fact that we will need lists for advantages, disadvantages, skills, and equipment. Backpacks can have a list of equipment as well, so we better be ready for that. In addition, weapons come in two forms: ranged and melee. All weapons have additional combat stats. Armor has a different set of combat stats. These things will have to be kept track of.
Let's start with the character sheet:
I will be talking about the classes Buyable, Equip, and Stat shortly. The idea is that these will represent classes for things bought with points (Buyable), money (Equip), or the results of those (Stat). Notice also that Languages, Advantages, etc are actually lists. Since most languages support a list construct of some sort (even if it's just an array), this is a fairly safe thing to do.Code:class character_sheet string name string player int point_total int height int weight int size_modifier int age int unspent points Stat ST Stat DX Stat IQ Stat HT Stat HP Stat Will Stat Per Stat FP Stat Basic_Lift Stat Thr Stat Sw Stat Basic_Speed Stat Basic_Move Stat DR Stat Parry Stat Block Stat Dodge Stat Encumberance int TL Stat Money Stat Appearance Stat Status Stat Reputation List<Buyable> Languages List<Buyable> Advantages List<Buyable> Disadvantages List<Buyable> Skills List<Equip> Hand_Weapons List<Equip> Ranged_Weapons List<Equip> Armor List<Equip> Misc string Notes
A Stat is simply a measure of a basic attribute. A "normal" person has ST 10, DX 10, IQ 10, and HT 10. From these, the others are calculated. The approach we will take is to simply let our class default all stats to appropriate values, and let other purchases modify them. Some stats have dual values. HP is an example. You have your max HP, and your current HP (after wounds, etc). As a result, we need to account for that in our Stat class. Also, some are calculated with decimal values. Basic Speed is a good example of this ((DX + HT)/ 4). We'll make it like this:
Getting more interesting is advantages, disadvantages, and skills. Each (dis-)advantage can have limitations or enhancements. This means a (dis-)advantage needs both a description and a list to store the limitations/enhancements. Further, when you are talking about something like "Ranged attack", you will not only want to define it more precisely through enhancements and limitations, you will also want a verbal description of what all this represents. "Area of effect, burning" could be a stream of fire, or chain lightning. Knowing which it is may have minor game-play effects.Code:class Stat int value int current float raw
(Dis-)advantages can also affect skills or attributes. +3 ST is obvious... until you realize that HP = ST. You will need to make sure any attributes calculated of others are accounted for. Other (dis-)advantages directly affect certain skills. For example, the advantage flexibility gives a +3 to the climbing skill. Talents give bonuses to a family of skills (sword talent, anyone?). Finally, a (dis-)advantage can be a racial package, which is a list of advantages, disadvantages, and skills that define a non-human race. These will have to be accounted for correctly. So, (dis-)advantages have to support: lists of enhancements/limitations, lists of attributes/skills to modify, sub-lists of (dis-)advantages and skills, and a description.
Buyable will look like this
We'll inherit Ad_Disad from Buyable to add the features we need for (dis-)advantages.Code:class Buyable string name string description int points
Bonuses are stored as a list of pairs to make it easier to apply. Enhance_Limit is just a name, description and a percentage (positive for enhancements, negative for limitations).Code:class Ad_Disad : class Buyable List<Pair<Stat,float>> stat_bonuses List<Pair<Skill,int>> skill_bonuses List<Skill> package_skills List<Ad_Disad> package_ads List<Ad_Disad> package_disads List<Enhance_Limit> enchancements List<Enhance_Limit> limitations
Skills are a little bit easier... at first glance. Each skill has a parent attribute. Each skill can have a list of defaults (usually other skills at a significant penalty). Each skill has a difficulty. A skill can have a list of prerequisite skills, advantages, disadvantages, or attributes (magery is common for magic spells, for example). Each skill has a controlling attribute and a difficulty, which determines how far below the attribute it will be for a given number of points.Code:class Enhance_Limit string name string description int percentage
Finally, many skills have a list of techniques that can be used with the skill. GURPS Martial Arts is basically a short list of skills and a LONG list of techniques to describe almost every known martial arts style documented! Some skills have to be bought at a specific tech level as well (programming ENIAC was very different from programming a game in VB.NET on Vista).
Notice that equipment will require similar types of classes. The development of those classes is left to you for funCode:class Skill : class Buyable Stat parent string difficulty int skill_level int TL bool TL_based List<Technique> techniques List<Buyable> prerequisites List<Pair<Skill,int>> default_skills List<Pair<Stat,int>> default_stats. Finally, there will need to be a way to tie all these things together. Because you can buy things in various orders, you can't have a fixed mechanism for calculating values. Instead, you will have to calculate the Stats, then skills, then modified skills every time a new skill/advantage/disadvantage is purchased. This tutorial doesn't begin to cover the methods for performing all the calculations.
Also, notice that there are further rules, such as mutually exclusive advantages and disadvantages. Except with the right enhancements and limitations, they might not conflict. It's important to decide what you will try to account for programmatically, and what you will leave to the Game Master (the sadist running this whole show, aka GM) for final approval. Since some options are not available in all settings, some things will have to be left to the GM.
As a final word, you may have noticed that there seems to be a LOT of data, and not much in the way of methods for these classes. Depending on who you talk to, the data may be hidden behind setters and getters, or may be better left exposed. The interface may impact this as well. Perhaps the classes are closely tied to the interface (a bad idea), or perhaps the interface just contains a copy of character_sheet and calls its methods as needed. The purpose of this exercise is not to finish this, but to get you thinking. If you want to see a solid implementation of these ideas, download the GURPS Character Sheet program and look at the source code. You may see a radically different implementation from what is described here. Then remember, it's a small program.


LinkBack URL
About LinkBacks

Thaumatology talks about completely different ways to handle magic (including a system similar to the Dungeons & Dragons one). The list of the things you can buy takes 10 pages in the Basic Set. We will NOT want to hard code that list.



Reply With Quote


. Thanx m8






Bookmarks