How would you create a Weapons class?

Started by
6 comments, last by Henderson 8 years, 3 months ago

If you were creating a Weapons class, would you make it properties-based, inheritance-based, or other?


public class Weapon
{
    Weapon(....) { .... }
    int HP;
    int MP;
    enum WeaponType;
    string name;
    var someProperty;
    
    // other properties and methods
}

or


public class BroadSword : Weapon
{
     // virtual methods and such here
}

or something else entirely? I'm not looking for a right or wrong answer. Just a some discussion on different ways to approach and why you would do so.

Beginner in Game Development?  Read here. And read here.

 

Advertisement
It depends. At a very basic level, do weapons have different logic/game rules or do they simply have different properties that are applied by the same rule?

Instead of inheritance can you apply composition? For example, let's say you can have a sword, and a flaming sword. A naive way to model this would be
Weapon <- Sword <- FlamingSword
Later on, you decide you want a poison sword. No problem just add it to the inheritance tree, right?

Weapon <- Sword <- FlamingSword
^
|
PoisonSword

Except now, every weapon branch has three classes (Dagger, FlamingDagger, PoisonDagger, etc)

Then what happens if you want a FlamingPoisonSword? It's the dreaded diamond inheritance pattern.

Instead, you could model your Weapon class with a DamageType component (I.e. Edge, Bludgeon, etc) with optional effect slots (Fire, Poison, etc).

And that's before we even get into data driven modelling...
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

I'd go for a composite way for weapons. The advantage is that you can easily create weapons at runtime and have a more dynamic approach at creating new weapon types.

Inheritence is bad for this because you will end up in having alot of classes which may depend on each other if you want something like a MagicFlamingDoubleEdgedBroadsword or something.

I'd take a look at the decorator pattern which is a great way to add new behaviour dynamicly.

Follow my hobby projects:

Ognarion Commander (Java/LIBGDX): https://github.com/OlafVanSchlacht/ognarion-commander


It depends.

^^ This ;) Letting external forces (deadlines, budget, objectives, engine requirements, …) aside, then of course data driven composed game objects is the way to go.

I would even say that it isn't necessary to have a class "Weapon". Isn't damage just an effect on a specific stat, induced by using an item in a specific way? Let's say the engine supports an StatActionEffect component class (perhaps inheriting ActionEffect). The designer adds an instance of StatActionEffect to a game object that represents an item. The instance is parametrized with e.g. intensity=-40, target=collider, stat=health. Let's further say that the player's game object is enabled to use item game objects (here isn't the place to elaborate on this, but you can ask if you want to hear more about this). When the item is successfully used during gameplay, then the existence of an ActionEffect component causes its application, and voila: a damage is applied. (Of course, when implementing such a thing, it is not really such easy.) Then anything, even a thrown vase, may be a "weapon".

Notice that, with the same reasoning, a class "Item" is also not strictly necessary. Thing is, one must stop thinking that OOP classes cardinally represent physical objects.

If I was making a weapon class... It'd be something like....


Class Weapon {
private:
string Name;
int32 Damage;
int32 Value;
int32 Durability;
e_type Type;

int Enchantment_count;
Enchantments* effects;

int UsabilityFlags;

public:
void attack (entity* target);
void break();
void drop();
void pickup();
}

Class Enchant {
public:
virtual void Apply( entity* target) = 0;
int charges;

}

A few important notes...

Enchantments are an array that is tied to the class via pointer. A weapon can have multiple atomic enhancements on it at once.
Both of these are simply base classes... however it does very little good if you want to have some weapons be unique in a fashion.

It is probably worth taking a look at what others have done to model weapons in this domain:

Doom 3 BFG

Quake 3 Arena

Torque 3D

There are tons of other engines out there that you can check out on Github. Inheritance is a common pattern it would seem for such a model based solely upon browsing others code.


There are tons of other engines out there that you can check out on Github. Inheritance is a common pattern it would seem for such a model based solely upon browsing others code.

I wouldn't recommend looking at 11-year old code as a source of inspiration though. Many things have evolved from then, and while the code might have been subjectively good at this point in time, doesn't mean it holds up today. Especially since you mentioned it, inheritance is being dropped in favour of composition nowadays, which offers many benefits.

Bottom line, if you want to make an educated obseration of what is "a common pattern", you need to look at modern code, not code from a decade ago. Big current engines like Unreal Engine 4 also use inheritance more than I feel comfortable with, but I don't feel qualified to comment on whether it is justified in that case based on how flexible, as well as easy-to-use they need to be, or if its just a decision based on "we've always done it that way"... in a more specific games code where you have full control over all decisions, composition wins big time over inheritance.

Yep, sure look at newer code and make the decision yourself. At the end of the day, they are your trade-offs to make.

For a great source of trade-offs, here is a great write-up from Thoughtworks.

This topic is closed to new replies.

Advertisement