Currently I'm working on a MUD as a hobby. Every 'action' in the game is implemented via abstract class Action and concrete sub-classes, like "Put", "Attack", "ChangeStance", etc.
I'm looking for suggestions on the design. It currently works, and is relatively open for expansion, but it just seems... messy. The architecture is especially messy in regards to sub-classes of Action which deal with Inventory functions.
These Action sub-classes contain three primary components:
- static ActionResult instantiateAction(String input) : This is called using reflection(so it has to be static)on the server, when a client enters a command that corresponds to this Action. The string is entered into another object which returns a Targetable object. If a Targetable object cannot be found, or if the object is not of enum TargetType.ITEM, then an ActionResult is returned with an error, the error is sent to the client(IE: "You can't pick that up, it's a monster!"), and the Action object is not created.
- Constructor():createNarratives() is called here in order to produce descriptions of the actions, which are in turn sent to clients. The action itself is also placed on the player's actionStack to be performed.
- initMechanics():This is called when the action is actually performed from a mob's actionStack. As part of these particular sub-classes, an inventory function is called like Stow(Targetable), which can assume that what its getting is an item and isnt null, but not things like whether or not the item is in hand for stowing. Therefore this too returns an ActionResult which is checked for errors. If it has errors, then createNarratives() is called again, and its original (successful) narratives are replaced with an error. (IE: That item is on the ground. Pick it up first.)
Like I said, not the worst architecture in the world, and it works, but we ARE talking about a lot of eggs in one basket: recognition and response to client's text entry, narrative creation and error messaging, and actual nuts and bolts mechanics. (Although the latter is fairly well encapsulated into the Inventory object, this is not the case with most other Action sub-classes. Most of them contain about 25-30 lines of mechanics code. This provides for a TON of customizability in action specifics, but only because the developer is forced to work really low-level at all times.)