Call of Duty games all have the core functionality of any FPS (walking around, killing, dying and repeat). Layered on top are various stuff. Of interest to me is during pre-game when you pick your perks. These perks can have very different effects and targets. Some affect walking speed and persist throughout the game, others are only activated at certain events and last for a certain duration. I am wondering what sort of design architecture/pattern would allow such a system that supports a wide variety of perks that have little in common.

For instance, imagine I want to add a perk that speeds up the rate of fire:

Do I make all my gun classes take as a constructor argument 'rateOfFire'? but then I will need to expand the code for each perk that affects the gun and the constructor gets bloated.

Maybe have it as a setter property on each gun? but then I can also bloat properties and make code insecure since I don't want anyone except the appropriate perks to change that property. I will also have to go back exposing more properties for each new perk. In addition, other classes that depend on this value might have already been initialized after the gun was created and acted upon the original 'rateOfFire' value before I get to change it.

and so on... and to further complexity, now imagine I want to add a new perk 'walk faster for 5 seconds after you die 5 consecutive times without killing anyone(death streak)'. This perk has nothing in common with the 'rateOfFire' perk.

And also there is the issue of how to deliver those chosen perks to their targets? I was thinking of the visitor pattern, but it seems inefficient since a perk that affects only certain guns will be passed to all game components that are customizable(level manager/presenter/physics and so on). And I will also need to expose their properties so that the perk can change them once visited.

I thought of other solutions that might work, but they all seem either too complex/over engineered. I am wondering how the Call of Duty developers might have implemented what seems to be a flexible and extensible perk system (many sequels).

Any suggestions are welcome.

Note am not remaking COD, instead I am making a simple mobile puzzle game but the perk problem is similar.

well you can boil it down to 'What design structures/patterns does a perk system such as that of the popular Call of Duty uses? where each perk can be completely different from another' I wrote alot to make my thoughts as clear as possible.
–
user964123Jan 28 '12 at 0:58

I still think it's too broad as per the "can you imagine a book written on the topic" criterion. You can probably use a majority of the Gang of Four somewhere in implementing a character customisation system. I'd say a better option would be looking at some open-source games with this sort of persistent status effect on players to see how they do it.
–
InerdialJan 28 '12 at 1:01

@ClassicThunder Very sorry, I quickly removed it since I felt this place was more appropriate and I didn't see any answer at moment of removal. Sorry Again. Inerdial am afraid maybe you misunderstood my question, Am not asking for a book long answer on specifics, I want an architectural/design overview of what would be used to allow such a system. I just need guidance...
–
user964123Jan 28 '12 at 1:13

4 Answers
4

class Perk {
Perk(GameObject* owner);
//called when this perk is added to perk list
//apply things that will stay as long as player has this perk
void onAdded();
//called when this perk is removed from perk list
//Usually to redo what you have done in onAdded
void onRemoved();
//called when this perk is activated
//apply things when the perk is activated
//For example, increase player speed and set the timeLeft to 5 secs
void activate();
//Undo things you've done in activate()
void deactivate();
//called each update
//for example, reduce the timer, when timer reach 0, call deactivate
void update(double deltaTime);
//Handle event
void onEvent(Event evt);
}

Gun attribute modifier: Gun should have two kind of attributes: baseAttribute and modifierAttribute. modifierAttribute can be accessed from anywhere. In your concrete Perk class, get modifierAttribute and do things, like: modifierAttribute.rateOfFire += 5. Gun class will consider the values in modifierAttribute when necessary. Separate those attribute is neat, because probably you'll need the original attribute (for example, increase rateOfFire by 5% effect).

For activating the perk based on certain event, you'll need event system in your game. When perk is added into the perk list, you'll register to certain event in the event system. Here is and example:

What you would need is a Perk class with a public map (or something) that stores the effects of perks. This class would also need access the Player object.

Perks fall into 2 general categories (off the top of my head)

Modify base stat

Give certain ability/item/new action

All perks that fall into category 1 can insert their modifier value into the map [rateOfFire; 1.1] and whenever that value needs to be used you just make sure to check the perk object as well. Also, you can determine which perks are permanent, put them in a separate map, and have all affected objects reference it at match setup.
For goal based perks, such as "+speed for 5 secs after killstreak" you just need an event trigger that modifies the Perk object.

For cat 2 perks (e.g. thing where you drop grenades as you die) you just need to code up actions, which a bunch of event triggers that get set at match setup based on a call to/from Perks class

Perhaps you can have a class Perk which contains read-only properties for each thing you want to perk. Then pass all the perks to your various classes in a List<Perk> whenever you need to. Inside the different classes of your game, you change each property that's relevant.