views:

135

answers:

2

Hi all,

I am doing a RogueLike game, and would like to make the logic for each entity modular. This probably could apply to web applications where there are roles and permission control too.

The idea is to have something like this - we have different type of entities in the game. a door can be bashed down, while a stone wall cannot be bashed. The logic module, say, could be a class called Bashable

public interface IBashable
{
    bool ProcessRequest(CharacterInfo character);
    string GetOutput();
    virtual int GetOutcome();
}

So a door with IBashable interface added to an object could be smashed. The ProcessReques() will use some rules to determine if the character manages to do so (perhaps a strength check).

An object without IBashable interface cannot be bashed open. The issue is - say a door have multiple logic components added to it. What I would like to do is to submit a request like this.

// Conan is derived from CharacterInfo class
BashDoorRequest request = new BashDoorRequest(conan);
Door d;
BashLogic bash;
PickLockLogic pick;
d.addLogic(bash);
d.addLogic(pick);

// Assuming the signature is processRequest(IRequest, where all request derived from)
d.processRequest(request)

The question is - how do I add the getmodules to activate? It is a BashDoorRequest, not PickLockRequest, so only the bash door logic would run.

I have two thinking - one is to use a visitor pattern, but it means quite a lot of classes added. The other is to have a tag or ID for each reach module and action. For example the bash logic may have a "bash" tag to it. Maybe I have two bash logic - one which allows players to bash the door, and another maybe, which reduces the HP of anyone bashing the door because it is spiked.

So I have to activate the two Logic Module for bashing, and the pick lock logic should not run. Should I have a hashamp of tags, and have each of the logic be grouped according to has?

This also apply to terrain; say characters cannot move through water. The water entity only has a ICannotWalk through logic added, but have a ISwimmable logic added. So how do I check only ICannotWalk module without wasting time to check the ISwimmable logic?

An other problem I am facing is the request object may have to take into more than one parameter, but passing in a hashtable to represent parameters feel like an overkill to me. Not to mention that some Logic Module may take in different parameters. (For example, a door is locked and requires a special key to open. The request for this would include the character's inventory too and not the the character info. Unless I pass the entire inventory, character's stats and everything to the Request.

Any ideas on how to implement this system will be welcomed!

A: 

Maybe the Command Dispatcher pattern can help you

AlberT
+1  A: 

You may want to read about the command pattern - what you are calling a request is essentially a command. Each object could maintain a list of CommandActions, and when a command is passed in, attempt to match each command against the list of available CommandActions.

Efficient dispatch of commands is often a challenge - especially when objects can respond to many different commands. There are several different ways to potentially resolve the performance issues:

  • Use a dictionary to match each command to its action based on a key shared by the two
  • Use command range groupings to narrow the search for an action based on key ranges
  • Assign each command a unique numeric ID and use binary search on an ordered collection to find actions
  • If more than one action can respond to a command, chain them together
  • Use specific methods to send common commands, rather than a generic ProcessRequest() method
LBushkin