10 Mar, 2010, Deimos wrote in the 1st comment:
Votes: 0
Just thought it would be interesting to see how you guys model the race/character relationship (for those who have races and OO code). Do you use composition or inheritance? Or some weird combination?

I'm kind of leaning toward a non-traditional(?) inheritance model, where a "race" (ex. Human) would just be a subclass of Creature, rather than a subclass of a Race class which Creature would instantiate. In my model, I would just leave the Race class out entirely. For those who -do- have a Race class, what kind of behavior does it implement that you don't think would logically fit into the Creature/Human classes?
10 Mar, 2010, Runter wrote in the 2nd comment:
Votes: 0
deimos said:
Just thought it would be interesting to see how you guys model the race/character relationship (for those who have races and OO code). Do you use composition or inheritance? Or some weird combination?

I'm kind of leaning toward a non-traditional(?) inheritance model, where a "race" (ex. Human) would just be a subclass of Creature, rather than a subclass of a Race class which Creature would instantiate. In my model, I would just leave the Race class out entirely. For those who -do- have a Race class, what kind of behavior does it implement that you don't think would logically fit into the Creature/Human classes?


Composition. I found it just to be more simple that way. Also, I found no reason to distinguish characters into objects based on race.
10 Mar, 2010, Tyche wrote in the 3rd comment:
Votes: 0
object $human
parents $creature;
endobject

object $orc
parents $creature;
endobject

object $half_orc
parents $human, $orc;
endobject
10 Mar, 2010, Runter wrote in the 4th comment:
Votes: 0
Tyche said:
object $human
parents $creature;
endobject

object $orc
parents $creature;
endobject

object $half_orc
parents $human, $orc;
endobject


object $half_half_orc
parents $human, $half_orc
endobject
10 Mar, 2010, Deimos wrote in the 5th comment:
Votes: 0
Runter said:
object $quarter_orc
parents $human, $half_orc
endobject

Fixed.
10 Mar, 2010, KaVir wrote in the 6th comment:
Votes: 0
I don't explicitly have races, but some of my classes (in particular dragon and titan) could also be considered races, and I've implemented classes using composition. It works okay, although in retrospect it might have been nicer to have gone with something a bit more generic (such as the background system I've proposed in the past). I wouldn't personally suggest using inheritance.

How will your approach handle shapechanging?
10 Mar, 2010, Deimos wrote in the 7th comment:
Votes: 0
KaVir said:
How will your approach handle shapechanging?

Each of my creatures (and possibly other non-creature entities in the future - I've left this open) has a "soul" compositioned into it, which, for NPCs, comprises the AI, and for PCs, comprises what's essentially just a socket IO wrapper. Shape-changing should be as easy as hot-swapping bodies for that soul, although admittedly, I don't have any kind of shape-changing system currently implemented and haven't given it any real thought so far, so I don't know yet if there are any pitfalls to this approach.
10 Mar, 2010, KaVir wrote in the 8th comment:
Votes: 0
deimos said:
Each of my creatures (and possibly other non-creature entities in the future - I've left this open) has a "soul" compositioned into it, which, for NPCs, comprises the AI, and for PCs, comprises what's essentially just a socket IO wrapper. Shape-changing should be as easy as hot-swapping bodies for that soul, although admittedly, I don't have any kind of shape-changing system currently implemented and haven't given it any real thought so far, so I don't know yet if there are any pitfalls to this approach.

If my wizard shapechanges into a dragon, then I still want access to my skills and spells, and I still want to be able to earn exp. You probably don't want game data like that tied in with the socket code though (particularly as mobs are also likely to need skills and spells, and perhaps even earn exp of their own).

Of course if you don't have shapechanging, and are sure you won't ever want to support it in the future, then this isn't likely to be a problem. But personally I think shapechanging is a pretty cool feature - not just for PCs, but also for staff (eg, providing builders with tools for designing unusually shaped mobs on the fly).
10 Mar, 2010, Deimos wrote in the 9th comment:
Votes: 0
KaVir said:
If my wizard shapechanges into a dragon, then I still want access to my skills and spells, and I still want to be able to earn exp. You probably don't want game data like that tied in with the socket code though (particularly as mobs are also likely to need skills and spells, and perhaps even earn exp of their own).

Just because you're swapping bodies doesn't mean you can't bring that stuff with you:

//  wizard is previously defined
Dragon dragon = new Dragon ();

wizard.shapeShift ( dragon );

// inside the shapeShift() method:
Creature oldBody = this.body;
this.body = dragon;
this.body.soul = this;
this.body.setStats ( oldBody.getStats () );
this.body.setSkills ( oldBody.getSkills () );

Obviously, this is a completely contrived example with bad coding practices, but hopefully you get what I'm trying to say.
10 Mar, 2010, shasarak wrote in the 10th comment:
Votes: 0
I think most of the advantages of separating out race into a property rather than a superclass derive from the ability to reference multipleraces with attributes summed or averaged across them. We've already mentioned half-orcs as a possibility: if you have two race prototypes, one for human and one for orc, and all racial properties are determined by averaging across the prototype collection, you don't have to explicitly define a HalfOrc class - you just use a combination of Orc and Human prototypes, and there's no coding required. This doesn't work so well with inheritance: if you have a HalfOrc class which inherits from both Orc and Human then (for example) its default strength score has to be inherited from one superclass or the other, it won't automatically equal that of both parent-classes averaged unless you write some more code to make it do that; and if you have to write explicit code, that means you need to write an explicit class for every possible combination.

You can potentially include rather more exotic prototypes, too. So, for example, you might have a FireUsing prototype, a FrostUsing prototype, etc. Fire-using creatures might be immune to heat-based attacks. To create a "red dragon" race you then combine a generic Dragon prototype with a FireUsing prototype, and you're nearly there; to create a white dragon, you combine Dragon and FrostUser prototypes, and so on. This sort of thing (using prototypes with no functional overlap) is possible with inheritance, but only if the language supports multiple inheritance - a red dragon needs to inherit from both Dragon and FireUser, other classes need to inherit from either one, but not both. And if you do it with prototypes this also gives you the option to interbreed red and white dragons and get creatures that have 50% resistance to both fire and frost!

Another useful prototype might be "Undead". So, to get a human zombie, you combine Human and Undead prototypes. To get a dragon zombie you combine Undead and Dragon. The point of doing it this way is you don't have to explicitly define what the properties of a dragon zombie are; if you've set up your Undead prototype correctly, it should be something you can apply to anyother race or species to get an undead version of it without any additional coding needed.
10 Mar, 2010, KaVir wrote in the 11th comment:
Votes: 0
deimos said:
Just because you're swapping bodies doesn't mean you can't bring that stuff with you

Right, but it's still pretty nasty to have to create a whole new body, copy a load of data over, then destroy the old body, every time you want to shapechange.

With composition, you can just do something like this:

pWizard->GetRace()->Set(IRace::eRaceDragon)
Or for a half-orc:

pWizard->GetRace()->Set(IRace::eRaceHuman, IRace::eRaceOrc)
Or whatever else you fancy.
10 Mar, 2010, shasarak wrote in the 12th comment:
Votes: 0
KaVir said:
If my wizard shapechanges into a dragon, then I still want access to my skills and spells, and I still want to be able to earn exp. You probably don't want game data like that tied in with the socket code though (particularly as mobs are also likely to need skills and spells, and perhaps even earn exp of their own).

Of course if you don't have shapechanging, and are sure you won't ever want to support it in the future, then this isn't likely to be a problem. But personally I think shapechanging is a pretty cool feature - not just for PCs, but also for staff (eg, providing builders with tools for designing unusually shaped mobs on the fly).

I have to say, I'm with deimos on this one. I agree that shape-changing is very cool, but what shape-changing requires is some form of separation between Mind and Body - that is, it has to be possible to take the player's Mind and put it in a different Body (and, indeed, potentially have the player's soul ripped from his body and immobilised while it is temporarily replaced by a demonic spirit which can walk around impersonating him!).

What we're discussing here is, assuming there is a separation between mind and body, if a player's body is human, should it be an instance of a Human class, or should "Human" be one of its properties? This is certainly important in other areas (see my previous post), but I don't see that it has any relevance to shape-shifting.

The Mind/Body separation does raise all kinds of interesting implementation (and even philosophical!) questions about whether things like skills or XP should be stored on the Mind or Body object. If someone is an expert swordsman, should he retain his sword-fighting skills if he temporarily finds himself trapped in the body of a puny mage? Is sword-fighting skill based more on intellectual learning or muscle memory? If you are possessed by a demon, should the demon be able to access your memory and cast spells that you know? Or if your body is under the control of an evil magician, should he be able to use it to cast spells with, or does the source of his magic depend on the physical properties of his own body?

Similarly, experience points could be a property of the mind rather than the body - but it's not necessarily obvious that experience gained in another body should benefit you when you get back to your own. That might well depend on thematic considerations.

(Either way, I'd say socket handling should be distinct from the Mind object).
10 Mar, 2010, Deimos wrote in the 13th comment:
Votes: 0
@shasarak:
Excellent points. What you're talking about sounds conceptually identical to KaVir's "background" system, actually. I really like the flexibility it seems to provide. I'll have to think on this one for a while.
10 Mar, 2010, Deimos wrote in the 14th comment:
Votes: 0
shasarak said:
(Either way, I'd say socket handling should be distinct from the Mind object).

For what reason(s)? You have to tie it in somewhere, and it's the mind/soul that you're actually controlling, which in turn is controlling the body. Or, at least, that's my reasoning. Where else would you put it?

Edit: I just realized that you may have meant that the actual implementation should be in, say, a Socket class, compositioned into the Mind/Soul class, rather than having the mind itself actually implement the socket-level behavior. Incidentally, this is how I currently have it designed, so if that's what you meant, then I agree.
10 Mar, 2010, KaVir wrote in the 15th comment:
Votes: 0
shasarak said:
I have to say, I'm with deimos on this one. I agree that shape-changing is very cool, but what shape-changing requires is some form of separation between Mind and Body - that is, it has to be possible to take the player's Mind and put it in a different Body (and, indeed, potentially have the player's soul ripped from his body and immobilised while it is temporarily replaced by a demonic spirit which can walk around impersonating him!).

I would argue that possession is a separate concept entirely. Personally, I think that if a muscular human shapechanges into a troll, they should become a muscular troll (i.e., their strength should remain the same, relative to their current species).

shasarak said:
What we're discussing here is, assuming there is a separation between mind and body, if a player's body is human, should it be an instance a Human class, or should "Human" be one of its properties? This is certainly important in other areas (see my previous post), but I don't see that it has any relevance to shape-shifting.

The inheritance approach becomes a problem if your "race" can be changed during play, and shapechanging is an obvious example of where that can happen. You don't want to have to destroy and create a new body, copying certain attributes over from the previous body, every time someone shapechanges.

You did actually agree with the aggregation approach the last time we discussed it. Did you encounter a scenario that changed your mind?
10 Mar, 2010, David Haley wrote in the 16th comment:
Votes: 0
I see little to no reason for races to be classes. A race, in nearly all cases, is a collection of properties, not a set of behaviors. What's the concrete gain in having the race "Human" derive from "Creature"?

Besides, as others have pointed out, treating races as data objects rather than as behavior classes affords you all kinds of flexibility. Shape-changing is just one of these aspects among very many, and no, inheritance is not a problem only when you can change the race during game-play. Indeed, the possibility of an undead orc vs. an undead human is very real; all undead things presumably share some properties as do all orcs and humans.

Using your inheritance scheme, you need either a ridiculous cross product (Human, UndeadHuman, Orc, UndeadOrc, ……) or you need to add every possible property to every "base race", so that all Humans have a flag "is undead". But what if you have different kinds of undead? What if you have weakling undead creatures vs. truly powerful undead creatures? (Maybe the necromancer was an amateur and so his creations are lousy.) Do you now have flags for each kind of undead? It rapidly becomes kind of silly.

Really, all of these things are just aspects of a creature, so to me it's difficult to argue that it should be anything other than composition of some sort, really. Of course, if none of that flexibility is applicable/relevant, then sure, you can do something simpler.
10 Mar, 2010, shasarak wrote in the 17th comment:
Votes: 0
deimos said:
shasarak said:
(Either way, I'd say socket handling should be distinct from the Mind object).

For what reason(s)? You have to tie it in somewhere, and it's the mind/soul that you're actually controlling, which in turn is controlling the body. Or, at least, that's my reasoning. Where else would you put it?

Edit: I just realized that you may have meant that the actual implementation should be in, say, a Socket class, compositioned into the Mind/Soul class, rather than having the mind itself actually implement the socket-level behavior. Incidentally, this is how I currently have it designed, so if that's what you meant, then I agree.

Yes. I prefer any given class to have a relatively simple, small, closely-related set of functions. You should be able to usefully sum up what it does in one sentence! If (for example) a player Mind is responsible for tracking XP and skills (so that when you move the mind into a different body, the XP and skills go with it) then it's clearly doing something entirely different from managing socket handling, so there's no earthly reason to put them in the same class, and in fact it complicates things if you do.
10 Mar, 2010, shasarak wrote in the 18th comment:
Votes: 0
KaVir said:
You did actually agree with the aggregation approach the last time we discussed it. Did you encounter a scenario that changed your mind?

No, no, I'm very much in favour of aggregation; I'm even in favour of using it to handle race (see post 10 in this thread). I just wasn't entirely convinced of its relevance to shape-shifting. But yes, the specific implementation of shape-shifting that you describe (where the physical properties of the new body are strongly influenced by the properties of the old one) probably does require Race or Species to be a body attribute.

When I think of a human being metamorphosed into a dragon, I guess I don't necessarily think in terms of a weedy human becoming a weedy dragon! Again, that might or might not be desirable, depending on thematic considerations. When Bruce Banner becomes The Hulk, you don't necessarily want him to be a weak Hulk simply because Banner is weak - it is precisely the contrast between the two states which makes the scenario interesting. Similarly, a weak person affected by lycanthropy shouldn't necessarily become a werewolf that is too weak to kill anybody; what makes lycanthropy interesting is a weak human becoming transformed into a powerful, lethal predator.
10 Mar, 2010, shasarak wrote in the 19th comment:
Votes: 0
David Haley said:
But what if you have different kinds of undead?

Good point: zombie human, vampire human, lich human, etc. I definitely want to play a MUD which allows me to become a vampire dragon! :smile:
10 Mar, 2010, David Haley wrote in the 20th comment:
Votes: 0
shasarak said:
If (for example) a player Mind is responsible for tracking XP and skills […] then it's clearly doing something entirely different from managing socket handling, so there's no earthly reason to put them in the same class

Well, if we're already separating mind, body and soul, maybe we've gone beyond earthly reasons… :wink:
0.0/91