Object Interaction - RyanBabij/WorldSim GitHub Wiki
What is a good system for developing interaction with/between objects in a game?
For example, if a player is interacting with a tree, they might want to chop it down, or they might want to climb it. The most obvious approach is to have chop() and climb() functions for the tree. However in this case you need to know whether the object is a tree or not. You can't climb a book, for example.
So if you wanted a more generic system, then you could create an interact() function. However how would you specify what type of interaction? How would the interacting object know how to deal with the result?
One possible solution is to create a list of possible interactions. "read", "open", "climb", etc. And pass those as an argument to the object. For example: book.interact("read"). A bad argument passed will just do nothing, so you don't need to worry about ensuring all possible interactions are valid. However this is not really a generic approach because by passing the argument, you are once again just specialising by object type.
One other possible solution is to create action classes. For example, Action_Read. Action_Read will allow interaction between a Character and a Book, but not a Tree. This is known as double dispatch A character will inherit a list of Actions which they can choose from. But how will the Character know what actions are valid between which objects?
I haven't really been able to come up with a perfect system for dealing with this issue. Inevitably you must maintain a list of actions with hardcoded specialisations. And AI must be written to deal with every possible action manually.
I think the best option is simply to split objects up into a group of categories, and each category may be managed separately. For example a book is a form of item. Items all have a read() function. Sword is a type of weapon, all weapons have an attack() function. This will eliminate type checking, but there will be useless functions. For example a Potion is a type of Item, but you can't read a potion. Calling that function will be valid, but nothing will happen. To deal with this, every item would need a canRead flag, which the AI can then check to see if there's anything to gain from actually calling the function. This is not ideal, but so far this is the best solution I have been able to come up with.