I was able to make some good progress over the weekend.
I completed the keyboard input handler. The player can now run around on the map and attack monsters. The game loop is holding up well and I’m happy with the design. Dead monsters are removed from the map and not included in any further game logic.
I am using the command pattern to encapsulate the attack and move functionality. This is working well so far, but I’m not completely happy with the coupling. My initial design was that the various commands would totally abstract the logic away from the main game loop. The various AI implementations are responsible for instantiating new commands and allowing the game loop to process these commands.
I always seem to need a reference to the actor initiating the command, the other actors on the map, the terrain, and the direction. This requires my AI implementations to hold too many irrelevant references, making them brittle. If my commands had an implicit reference to the actors, terrain, objects, etc. then I would only need to pass them a reference to the initiator (the AI host) and a direction. To remedy this I propose to add some kind of factory that knows about the current game state.
I currently don’t have a concept of an encapsulated game state, as I haven’t needed it. But the design is now requiring such a construct. I’m thinking of creating the concept of an instance. The instance would represent a dungeon level or town area. I don’t know if it will represent multiple dungeon levels, but it could.
The AI would then ask the current game instance for a new Move or Attack command and pass it the Actor and Direction as input parameters. The game instance would instantiate the requested command with the appropriate data for the AI which would then pass it back to the game loop. The coupling will now be reduced to a single instance class which should prove to be easier to work with.