Note: Although this tutorial is written using Flash and AS3, you should be able to use the same techniques and concepts in almost any game development environment.
Introduction
Attributes systems are very commonly used in RPGs to quantify characters’ strengths, weaknesses, and abilities. If you’re not familiar with them, skim the Wikipedia page for a decent overview.To make them more dynamic and interesting, developers often improve these systems by adding skills, items and other things that affect the attributes. If you want to do this, you’ll need a good system that can calculate the final attributes (taking into consideration every other effect) and handle the addition or removal of different types of bonuses.
In this tutorial, we will explore a solution for this problem by using a slightly modified version of the Composite design pattern. Our solution will be able to handle bonuses, and will work on any set of attributes you define.
What Is the Composite Pattern?
This section is an overview of the Composite design pattern. If you are already familiar with it, you might want to skip to Modeling Our Problem.The Composite Pattern is a design pattern (a well-known, reusable, general design template) for subdividing something big into smaller objects, in order to create a bigger group by handling only the small objects. It makes it easy to break big chunks of information into smaller, more easily treatable, chunks. Essentially, it’s a template for using a group of a particular object as though it was a single object itself.
We’re going to use a widely used example to illustrate this: think of a simple drawing application. You want it to let you draw triangles, squares and circles, and treat them differently. But you also want it to be able to handle groups of drawings. How can we easily do that?
The Composite Pattern is the perfect candidate for this job. By treating a “group of drawings” as a drawing itself, one could easily add any drawing inside this group, and the group as a whole would still be seen as a single drawing.
In terms of programming, we would have one base class,
Drawing
, which has the default behaviors of a drawing (you can move it around, change layers, rotate it, and so on), and four subclasses, Triangle
, Square
, Circle
and Group
. In this case, the first three classes will have a simple behavior, requiring only the user input of the basic attributes of each shape. The
Group
class, however, will have methods for adding and removing shapes, as well as doing an operation on all of them (for example, changing the color of all shapes in a group at once). All four subclasses would still be treated as a Drawing
, so you don’t have to worry about adding specific code for when you want to operate on a group.To take this into a better representation, we can view each drawing as a node in a tree. Every node is a leaf, except for
Group
nodes, which can have children — which are in turn drawings inside that group.A Visual Representation of the Pattern
Sticking with the drawing app example, this is a visual representation of the “drawing application” we thought about. Note that there are three drawings in the image: a triangle, a square and a group consisting of a circle and a square:And this is the tree representation of the current scene (the root is the drawing application’s stage):
What if we wanted to add another drawing, which is a group of a triangle and a circle, inside the group we currently have? We would just add it as we would add any drawing inside a group. This is what the visual representation would look like:
And this is what the tree would become:
Now, imagine that we’re going to build a solution to the attributes problem we have. Obviously, we’re not going to have a direct visual representation (we can only see the end result, which is the calculated attribute given the raw values and the bonuses), so we’ll start thinking in the Composite Pattern with the tree representation.
Modeling Our Problem
In order to make it possible to model our attributes in a tree, we need to break each attribute into the smallest parts we can.We know we have bonuses, which can either add a raw value to the attribute, or increase it by a percentage. There are bonuses which add to the attribute, and others that are calculated after all those first bonuses are applied (bonuses from skills, for example).
So, we can have:
- Raw bonuses (added to the raw value of the attribute)
- Final bonuses (added to the attribute after everything else has been calculated)
These two kind of bonuses are only the leaves of our tree. They are pretty much like the
Triangle
, Square
and Circle
classes in our example from before. We still haven’t created an entity that will serve as a group. These entities will be the attributes themselves! The
Group
class in our example will be simply the attribute itself. So we will have an Attribute
class that will behave like any attribute.This is how an attribute tree could look:
Now that everything is decided, shall we start our code?
Creating the Base Classes
We will be using ActionScript 3.0 as the language for the code in this tutorial, but don’t worry! The code will be fully commented on afterwards, and everything that is unique to the language (and the Flash platform) will be explained and alternatives will be provided — so if you are familiar with any OOP language, you will be able to follow this tutorial without problems.The first class we need to create is the base class for any attribute and bonuses. The file will be called
BaseAttribute.as
, and creating it is very simple. Here is the code, with comments afterwards: [...]Read more: Using the Composite Design Pattern for an RPG Attributes System