Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > cant find a pattern to fit neatly - how to make a large number of monsters?

Reply
Thread Tools

cant find a pattern to fit neatly - how to make a large number of monsters?

 
 
steve mathers
Guest
Posts: n/a
 
      01-23-2005
Hi , fairly new to OO design. Trying to solve a problem:

problem:
I want to make a large number of different monsters. what makes
monsters different from each other is their 'abilities'. These could
such things as carrying a weapon or magic item that allows them to
perform an action, or something like an intrinsic resistance to attack
with fire, or a temporary ability ability granted by a spell cast on
them.

* I want to be able to define different monster types and different
ability types using as little memory as possible (mobile phone
platform) - a hard coded table of abilities and then another table of
monsters that lists which ability each monster has. Some sort of
factory will have to create the monster given an index into this
table. Thats not the hard part.

* I want to be able to add new monsters and new abilities to the table
without changing the inteface of the monster and ability class. I
think this is the hard part.

solution: At first thought, the decorator pattern seems right, but
because abilities can come and go all the time, it seems to be
unweildy.

I think what I want to happen is that every time the monster has to do
something that involves its characteristics which may be modified by
abilities (such as fire resistance), or it wants to perform an
optional action that an ability may bestow it with (such as hit
something with a weapon), it should interogate its entire list of
current abilities to see if they impact on that charicteristic or
action. But how to structure that process in my design?

Is there a particular pattern I should be looking at?

thanks,

Steve
 
Reply With Quote
 
 
 
 
thufir
Guest
Posts: n/a
 
      01-23-2005

steve mathers wrote:
> Hi , fairly new to OO design. Trying to solve a problem:

[..]
> I think what I want to happen is that every time the monster has to

do
> something that involves its characteristics which may be modified by
> abilities (such as fire resistance), or it wants to perform an
> optional action that an ability may bestow it with (such as hit
> something with a weapon), it should interogate its entire list of
> current abilities to see if they impact on that charicteristic or
> action. But how to structure that process in my design?

[..]

That sounds very computationally intensive to me. Depending on the
size of the table, mightn't that create more of a strain than keeping a
mobs characteristics within a single object?

I've always heard that it's better to focus on design first and
performance second. As an alternative, what's wrong with a very simple
mob composed different "parts," like FireResistance.

--
Thufir Hawat

 
Reply With Quote
 
 
 
 
stevenmathers@yahoo.com
Guest
Posts: n/a
 
      01-24-2005
performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.


example of the process I was thinking of:

monster object: holds intrinsic characteristics and list of optional
abiltiies

ability object: enables monster to perform some function, and/or
modifies some of its abilities.

so there is a dependency there between monster and ability, but how to
make it as weak as possible. The vector of change is definately more
types of abilities, and more types of monsters.

use case 1: monster makes a melee attack: it interrogates each of its
abilities: are you my current melee weapon, and if so, what type and
degree of damage do you do?

use case 2: monster needs to use its SPEED characetristic to determine
if it is its turn to act yet. it interogates all its current
abilities: here is my current SPEED - modify it if you will.

Perhaps there is a better system?



thufir wrote:
> steve mathers wrote:
> > Hi , fairly new to OO design. Trying to solve a problem:

> [..]
> > I think what I want to happen is that every time the monster has to

> do
> > something that involves its characteristics which may be modified

by
> > abilities (such as fire resistance), or it wants to perform an
> > optional action that an ability may bestow it with (such as hit
> > something with a weapon), it should interogate its entire list of
> > current abilities to see if they impact on that charicteristic or
> > action. But how to structure that process in my design?

> [..]
>
> That sounds very computationally intensive to me. Depending on the
> size of the table, mightn't that create more of a strain than keeping

a
> mobs characteristics within a single object?
>
> I've always heard that it's better to focus on design first and
> performance second. As an alternative, what's wrong with a very

simple
> mob composed different "parts," like FireResistance.
>
> --
> Thufir Hawat


 
Reply With Quote
 
thufir
Guest
Posts: n/a
 
      01-24-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> performance not an issue in this application, but codebase size is.
> and it would be nice to be able to add new types of abilities and
> monsters to the system just by adding a few bytes to a table and a
> function or two to handle them, and then have a factory creatre them

at
> runtime.


If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...

> example of the process I was thinking of:
>
> monster object: holds intrinsic characteristics and list of optional
> abiltiies


instead of a list of abilities, try for objects

> ability object: enables monster to perform some function, and/or
> modifies some of its abilities.


As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects

> so there is a dependency there between monster and ability, but how

to
> make it as weak as possible. The vector of change is definately more
> types of abilities, and more types of monsters.


Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.

> use case 1: monster makes a melee attack: it interrogates each of

its
> abilities: are you my current melee weapon, and if so, what type and
> degree of damage do you do?


public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}


> use case 2: monster needs to use its SPEED characetristic to

determine
> if it is its turn to act yet. it interogates all its current
> abilities: here is my current SPEED - modify it if you will.


how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?

> Perhaps there is a better system?


<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.


--
Thufir Hawat

 
Reply With Quote
 
thufir
Guest
Posts: n/a
 
      01-24-2005
(E-Mail Removed) wrote:
> performance not an issue in this application, but codebase size is.
> and it would be nice to be able to add new types of abilities and
> monsters to the system just by adding a few bytes to a table and a
> function or two to handle them, and then have a factory creatre them

at
> runtime.


If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...

> example of the process I was thinking of:
>
> monster object: holds intrinsic characteristics and list of optional
> abiltiies


instead of a list of abilities, try for objects

> ability object: enables monster to perform some function, and/or
> modifies some of its abilities.


As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects

> so there is a dependency there between monster and ability, but how

to
> make it as weak as possible. The vector of change is definately more
> types of abilities, and more types of monsters.


Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.

> use case 1: monster makes a melee attack: it interrogates each of

its
> abilities: are you my current melee weapon, and if so, what type and
> degree of damage do you do?


public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}


> use case 2: monster needs to use its SPEED characetristic to

determine
> if it is its turn to act yet. it interogates all its current
> abilities: here is my current SPEED - modify it if you will.


how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?

> Perhaps there is a better system?


<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.


--
Thufir Hawat

 
Reply With Quote
 
thufir.hawat@mail.com
Guest
Posts: n/a
 
      01-24-2005
(E-Mail Removed) wrote:
> performance not an issue in this application, but codebase size is.
> and it would be nice to be able to add new types of abilities and
> monsters to the system just by adding a few bytes to a table and a
> function or two to handle them, and then have a factory creatre them

at
> runtime.


If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...

> example of the process I was thinking of:
>
> monster object: holds intrinsic characteristics and list of optional
> abiltiies


instead of a list of abilities, try for objects

> ability object: enables monster to perform some function, and/or
> modifies some of its abilities.


As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects

> so there is a dependency there between monster and ability, but how

to
> make it as weak as possible. The vector of change is definately more
> types of abilities, and more types of monsters.


Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.

> use case 1: monster makes a melee attack: it interrogates each of

its
> abilities: are you my current melee weapon, and if so, what type and
> degree of damage do you do?


public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}


> use case 2: monster needs to use its SPEED characetristic to

determine
> if it is its turn to act yet. it interogates all its current
> abilities: here is my current SPEED - modify it if you will.


how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?

> Perhaps there is a better system?


<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.


--
Thufir Hawat

 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      01-24-2005
thufir wrote:

> Creature blobMonster = new Monster("blob");
> blobMonster.armWith("sword");


Shouldn't you also have:

blobMonster.armWith("arm");

in there somewhere ?




-- chris


 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      01-24-2005
(E-Mail Removed) wrote:

> performance not an issue in this application, but codebase size is.
> and it would be nice to be able to add new types of abilities and
> monsters to the system just by adding a few bytes to a table and a
> function or two to handle them, and then have a factory creatre them at
> runtime.


I think you are heading in the direction of a fairly complicated and abstract
bit of object modelling; I suggest that you take a step back and consider how
much flexibility you actually /need/. Also I'd suggest that, whatever degree
of flexibility you finally choose to implement, you try designing a version of
the system (and doing a small trial implementation) /without/ considering the
memory footprint -- you may find that you've gone up an over-abstract blind
alley.

It is one thing to able to mix and match different amounts of each of some
pre-defined list of "abilities" to build new and terrible monsters. That's
easy enough to do using classical OO. But wanting to be able to give monsters
new /kinds/ of ability with the same ease, will require a higher level of
abstraction; quite possibly your eventual system would look more like a
knowledge-representation kit, or a Lisp interpreter.

You might find that a hybrid approach would work. Most of your logic "knows"
about hardwired abilities (speed for instance) which every monster has to some
degree (possibly zero or even negative) and has specific code for handling
those aspects (e.g. using strength(), currentLoad(), and currentNumberOfArms()
to determine whether the monster can pick something up). In addition you have
a (much) less flexible, but more data-driven extension mechanism for adding a
little colour to your monsters. E.g. you could have Attack and Defence
classes, where:

class Attack
{
String name;
float strength;
int attackID;
}

class Defence
{
String name;
float strength;
int attackID;
}

and the idea is that you can add new Attack and Defence objects easily
(representing intrinsic abilities or abilities conferred by objects/events),
but your actual logic for dealing with them is very limited -- you just
consider every Defence with the same attackID as each launched Attack, and
add/subtract all the strengths before using that to change the victim's
lifeForce(). Or you could generalise that a bit -- e.g. each Attack and
Defence might have a defined effect on all of the victims pre-defined
attributes (speed etc.).

-- chris


 
Reply With Quote
 
H. S. Lahman
Guest
Posts: n/a
 
      01-24-2005
Responding to Mathers....

> Hi , fairly new to OO design. Trying to solve a problem:
>
> problem:
> I want to make a large number of different monsters. what makes
> monsters different from each other is their 'abilities'. These could
> such things as carrying a weapon or magic item that allows them to
> perform an action, or something like an intrinsic resistance to attack
> with fire, or a temporary ability ability granted by a spell cast on
> them.
>
> * I want to be able to define different monster types and different
> ability types using as little memory as possible (mobile phone
> platform) - a hard coded table of abilities and then another table of
> monsters that lists which ability each monster has. Some sort of
> factory will have to create the monster given an index into this
> table. Thats not the hard part.
>
> * I want to be able to add new monsters and new abilities to the table
> without changing the inteface of the monster and ability class. I
> think this is the hard part.
>
> solution: At first thought, the decorator pattern seems right, but
> because abilities can come and go all the time, it seems to be
> unweildy.
>
> I think what I want to happen is that every time the monster has to do
> something that involves its characteristics which may be modified by
> abilities (such as fire resistance), or it wants to perform an
> optional action that an ability may bestow it with (such as hit
> something with a weapon), it should interogate its entire list of
> current abilities to see if they impact on that charicteristic or
> action. But how to structure that process in my design?


I don't think this is a design pattern issue; I think it is more of a
tactical OOP optimization of a basic OOA/D. Per your first asterisk you
have:

[Monster]
+ type
| *
|
|
| *
[Ability]

which can be reified to:

[Monster]
+ type
| *
|
|
| 1
[AbilitySet]
| 1
|
|
| *
[Ability]

So each Monster has a reference to a table of its specific abilities.
(If you need to navigate the other way, each Ability has a reference to
a table of the Monsters with that Ability.)

As an OOP optimization you can eliminate the collections by being clever
about the identity of Abilities. Assuming the total number of Abilities
is relatively limited, you can implement AbilitySet as a bitmap
attribute of Monster where the bit position is the index into a fixed
array of Ability references accessed by a static Ability::find(index).
If the bit is set, the Monster has that Ability. Ability has a static
table of its instances that is updated as the instances are created.

The factory that creates Monsters can use external configuration data to
obtain the bitmap value for a particular Monster type based on the
Monster.type attribute. That can be read directly from a database. If
the user can create custom monsters, then one can store the bitmap and
the new type attribute for future reference.

This pretty much limits memory to M Monsters + N Abilities + 1 static
Ability table. The price will be performance in searching the bitmap
and checking the Abilities to see if they are relevant.

Note that at the cost of more bitmap attributes in Monster, one can also
save the searching. The basic idea is to cross-reference Abilities with
the Monster behaviors in exactly the same way:

[Monster]
+ type
| *
|
|
| *
[BehaviorSet]
| 1
|
|
| *
[Ability]

where each BehaviorSet is a list of references to the Abilities that are
relevant to a particular Monster behavior. In effect there is a
BehaviorSet bitmap for each behavior that Monster has. These would be
initialized in the same way as the first case.

The next issue is providing a generic interface to Ability. From the
examples cited, it seems that Abilities provide rather simple parametric
data that affects or enables certain Monster behaviors. That is,
Ability has no intrinsic behaviors. If so, I would suggest Ability be
in a form similar to an A-V pair. (There are many variations, such as
XML strings.)

Then the relevant Monster behavior can test the the attribute name to
determine how to apply the value in its context. (The direct search via
AbilitySet would simply ignore attributes that were not relevant to the
behavior in hand.) Then there is only one interface needed:
getAttribute and getValue. (Note there is nothing to prevent an Ability
from have multiple A-V pairs; the interface just has to be slightly more
flexible.)

[This sort of parametric polymorphism is a sort of analysis pattern,
BTW. I have a number of examples that might be of interest on my blog
in the section on invariants.]

*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
(E-Mail Removed)
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog (under constr): http://pathfinderpeople.blogs.com/hslahman
(88-OOA-PATH



 
Reply With Quote
 
thufir
Guest
Posts: n/a
 
      01-25-2005
Chris Uppal wrote:
> thufir wrote:
>
> > Creature blobMonster = new Monster("blob");
> > blobMonster.armWith("sword");

>
> Shouldn't you also have:
>
> blobMonster.armWith("arm");
>
> in there somewhere ?
>
>
>
>
> -- chris


grrrrr

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
cant compile on linux system.cant compile on cant compile onlinux system. Nagaraj C++ 1 03-01-2007 11:18 AM
cant find a pattern to fit neatly - how to make a large number of monsters? steve mathers Java 0 01-23-2005 11:52 PM
Make wxListCtrl fit around contents and parent frame fit around listctrl Piet Python 0 07-18-2004 08:27 AM
Neatly truncating text to fit a physical dimension Geoff Soper Javascript 2 01-26-2004 08:03 PM
Backup your projects neatly Guy C++ 2 10-03-2003 04:40 AM



Advertisments