Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Architecture for Game - To couple or not to couple?

I'm building a simple game which consists of Mobiles -- the in-game characters (Mobs). Each mob can perform certain functions. In order to give that functionality to the Mob, I've created a Behavior.

For example, let's say a mob needs to move around the game field, I would give it the MoveBehavior - this is added to an internal list of Behaviors for the mob class:

// Defined in the Mob class
List<Behavior> behaviors;

// Later on, add behavior...
movingMob.addBehavior(new MovingBehavior());

My question is this. Most behaviors will manipulate something about the mob. In the MoveBehavior example, it will change the mob's X,Y position in the world. However, each behavior needs specific information, such as "movementRate" -- where should movementRate be stored?

Should it be stored in the Mob class? Other Mobs may attempt to interact with it by slowing/speeding up the mob and it's easier to access at the mob level... but not all mobs have a movementRate so it would cause clutter.

Or should it be stored in the MoveBehavior class? This hides it away, making it a little harder for other mobs to interact with - but it doesn't clutter up a non-moving mob with extra and un-used properties (for example, a tower that doesn't move would never need to use the movementRate).

like image 948
bugfixr Avatar asked Jun 25 '09 16:06

bugfixr


2 Answers

This is the classic "behavioral composition" problem. The trade-off is that the more independent the behaviors are, the more difficult it is for them to interact with each other.

From a game programming viewpoint, the simplest solution is a decide on a set of "core" or "engine" data, and put that in the main object, then have the behaviors be able to access and modify that data - potentially through a functional interface.

If you want behavior specific data, that's fine, but to avoid collisions in the names of variables, you may want to make the interface for accessing it include the behavior name. Like:

obj.getBehaviorValue("movement", "speed")

obj.setBehaviorValue("movement", "speed", 4)

That way two behaviors can both define their own variables called speed and not collide. This type of cross-behavior getters and setters would allow communication when it is required.

I'd suggest looking at a scripting language like Lua or Python for this..

like image 178
sean riley Avatar answered Sep 23 '22 13:09

sean riley


You could borrow a pattern from WPF (attached properties). The WPF guys needed a way to sort of attach properties to controls at run time. (for example, if you put a control inside a grid, it would be nice for the control to have a Row property -- they pseudo did this with attached properties.

It works something like: (note this probably doesn't precisely match WPF's implementation, and I'm leaving out the dependency property registration, as you aren't using XAML)


public class MoveBehavior: Behavior
{
  private static Dictionary<Mob, int> MovementRateProperty;

  public static void SetMovementRate(Mob theMob, int theRate)
  {
     MovementRateProperty[theMob] = theRate;
  }

  public static int GetMovementRate(Mob theMob)
  {
      // note, you will need handling for cases where it doesn't exist, etc
      return MovementRateProperty[theMob];
  }
}

The thing here is that the Behavior owns the property, but you don't have to go spelunking to get it Here's some code that retrieves a mob's movement rate:


// retrieve the rate for a given mob
int rate = MoveBehavior.GetMovementRate(theMob);
// set the rate for a given mob
MoveBehavior.SetMovementRate(mob, 5);
like image 39
JMarsch Avatar answered Sep 20 '22 13:09

JMarsch