I've been entertaining myself lately by programming a simple text-based adventure game, and I'm stuck on what seems like a very simple design issue.
To give a brief overview: the game is broken down into
Room objects. Each
Room has a list of
Entity objects that are in that room. Each
Entity has an event state, which is a simple string->boolean map, and an action list, which is a string->function map.
User input takes the form
[action] [entity]. The
Room uses the entity name to return the appropriate
Entity object, which then uses the action name to find the correct function, and executes it.
To generate the room description, each
Room object displays its own description string, then appends the description strings of every
Entity description may change based on its state ("The door is open", "The door is closed", "The door is locked", etc).
Here's the problem: using this method, the number of description and action functions I need to implement quickly gets out of hand. My starting room alone has about 20 functions between 5 entities.
I can combine all actions into a single function and if-else/switch through them, but that's still two functions per entity. I can also create specific
Entity sub-classes for common/generic objects like doors and keys, but that only gets me so far.
Basically, I'm wondering if there are some alternatives to having entire source files dedicated to implementing non-reusable behavior functions. I'm using C++ but I'm thinking about moving the actual game code to Lua so I can use anonymous functions for behavior and tables for storing event state. I'm a competent programmer, so the implementation of any solution is a non-issue. My question is more conceptual.
EDIT 1: As requested, pseudo-code examples of these action functions.
string outsideDungeonBushesSearch(currentRoom, thisEntity, player) if thisEntity["is_searched"] then return "There was nothing more in the bushes." else thisEntity["is_searched"] := true currentRoom.setEntity("dungeonDoorKey") return "You found a key in the bushes." end if string dungeonDoorKeyUse(currentRoom, thisEntity, player) if getEntity("outsideDungeonDoor")["is_locked"] then getEntity("outsideDungeonDoor")["is_locked"] := false return "You unlocked the door." else return "The door is already unlocked." end if
Description functions act in pretty much the same way, checking state and returning the appropriate string.