Please take some time to read my questions. Thank you.
My current C++ exercise project is a win32-console text-only MUD engine. (MUD = "Multi-User-Dungeon" referring to the game genre in which the player wanders around in a 'map' of 'rooms' and can interact with many 'items' and 'characters'. In the text only example, this is done by entering commands such as "go north" "view room" "take hammer" "open chest" etc.) Being that my goal is for exercise (and not for some assignment i need to get done), also since a project like this involves many common concepts used in any C++ game project (or any C++ project for that matter), i wanted to inquire about several questions and issues that came up when i was designing this project.
First let me start with an example of what gameplay i am expecting:
Robot is activated.
UT (=user types): "view room" robot reports room description.
UT: "Take <object>" robot takes object into inventory.
UT: "take north wall" robot reports it cannot take the wall.
UT: "use <device>" robot activates device and reports device's interface view.
UT: "option 1" robot chooses option 1 on device, <machine> <does something> or <lights> <turn on> etc.
UT: "exit 34" robot exits door #34.
Upon entering adjacent room, robot is detected by sensor, a signal is sent to guard 5 rooms away, guard is making his way to current room.
UT: "test detection" robot scans for detectors and cameras, reports been detected.
UT: "use plasmagun" robot appropiates plasmagun, reports ready for combat.
Issue #1: Vast-Variety versus Inheritance & Polymorphism
I want my MUD to support a vastly variable variety of objects, each having x amount of data (members) and x amount of behaviours (methods). All of these objects should be stored in a single container (by sharing a common base class and having the container hold pointers).
Obviously the answer is inheritance and polymorphism, however, i realized (tell me if im wrong) that polymorphism is useful when designing a hiearchy that has SOME common behaviour and data structure, just that derived types differ in the way they do func() (= a base class function). But here i am dealing with a hiearchy which has too much variety. A flashlight object will probbably have a bool (on/off) and a switch() function, a vehicle object will have several driving functions, and a pda will have vectors of files and tons of interface functions. Many objects will be carriable, destroyable, movable, openable, closable, droppable, startable, stoppable, interfaced, single-useable, multi-useable, insertable, effective, detectable, invisible, etc. etc. etc. while many other objects will not. There are too many capabilities such as these to mention here, switchable, drivable, pressable, wheighted, electric, and any other concept that can turn up from the game story itself... Any object may have any combination of any of the capabilities said above. How to go about designing the hiearchy?
Should i make a class for every single type of capability (something like utility classes or mixins), then have objects inherit from any of the capability classes needed? I get the impression that thats alot of overhead and using lots of memory.
This issue is intertwined with the rest of the issues discussed, read on.
Apparently, my MUD is futile without RTTI. As said above, im planning to store all objects in a single container. When a certain command is to be executed upon an object, the object is checked if it can actually do it. This will be either with RTTI or with my own defined rtti (like an enum TYPE variable every object will have, etc.)
I read it all over that RTTI is frowned at and shows on bad design. Any advice?
Who is in charge of executing x? lets say our game object contains the player object and the map object. When the user commands the player to take an object from a room, the pointer to the object needs to be removed from the map's room('s container) and added to players inventory('s container). Should the player access the object? Should the object-container access the player? should the command handler send a signal to the game object to conrol the transfer 'from above'? after all, the game object contains the player and the map, he should be the one operating between them. Or, should the game & objects be contained differently than mentionned above?
Taking an object from a room is just an example. Who should take care of actions affecting the game mission, actions affecting the MUD options, creating/destroying objects in the map, or in the player, etc.?
4: Updates; "Hard coding" versus "Soft coding"
So far my projects are designed in a way that the game engine with all its details are hard-coded in the exe file my compiler produces, and some files that stick around the exe are just directives which the exe will load to know in which order and in which setting to create the map & objects & how many of them to create etc, though what is a map / what is an object is hard-coded in the exe. Thinking in the long run, after my game ships to the market, what if one day i want to invent one or more new types of objects, to be added somewhere in the hiearchy? or change some behaviour of existing objects, etc.? Do i have to recompile, then post the entire exe on my game website as 'download update 1.1 - 500MB'? (a thought; is there a way to make an updater-setup program which can add and change small changes in the exe file itself?)
Then i had the soft-coding idea, which might solve not only this issue but also the others mentioned before; I can make a small exe which will be an interface between c++ and my files. I will basically be inventing my own programming language, with all necessary logic rules, comparison rules, etc etc. Then, i will 'program' the MUD in external files, what is a map, what is an object, command strings which will execute comparisons and actions, etc. The exe will then 'compile' the game from the files, learn what is a flashlight and how does it work. There is a common denominator between all actions performed in all commands in the MUD; they all do one or more of the following;
-print text to console
-get data (from any object)
-set data (of any object)
-transfer containment of objects
-perform logic and execute conditionally
There can be ultimate variety of objects and their behaviours.
When there are any updates as to how a flashlight works, or a new type of flashlight etc, all that needs to be updated are the files.
Some issues of the soft-coded idea include; 1) Why dont i USE c++ instead of re-inventing it. (is it possible to update an exe file?) 2) I thought i learned that one of the ideals of c++ is not to separaete data from operations. Objects should execute whatever execution concerns themselves. But in the soft-coded idea, the objects are just variables which only set and get themselves, and at most contain strings of commands as to how they behave. But the flashligt's action of turning on (for example) is executed elsewhere completely- probably in the execution handler which received the behaviour string from the flashlight. 3) How should the ultimate template-object be designed, an object which can have any amount of data decided at runtime based on the loaded file's info? 4) Arent there enough levels of abstraction already; Binary, Hex, Machine code, Assembly, C++, and now my level of abstraction?
5: Main issue
Anytime i face c++ issues as such, i always wonder how do they actually do it out there in real companies & developing teams. Do they 'hard code' or 'soft code', or something else altogether? How do they conceptualize their class hiearchies? How do they update their programs with small update packages you download from the website? How do they setup which object is in charge of what? (browsing through my Warcraft 3 directories, i see that the warcraft3.exe is only 268 KB, and another war3.exe of 1536 KB, but there is a war3.mpq file which is 430.5 MB big, makes me beleive they do the soft-coding way...)
Thank you, if possible, please answer to
<<email id snipped>>