Hi.
I just finished programming an attempt at a “component-based” roguelike system, for practice. It was done over the last 4 days. You can get it here:
http://www.mediafire.com/?61s2vlh9dqiz73vThe code is rough and isn't meant for production work, just for practice, and I've got some questions because there were a number of things I wasn't quite sure how to do “right”, especially not with the new style of architecture I was triying here. It's a simple “curses”-based terminal program and the compile script is for Linux and similar systems – since I use Linux for most of my computing and programming work. Though it shouldn't be too hard to modify it to make it compile on Windows as a console app, provided you can supply the curses functionality with a suitable library (I haven't tried it on Windows, though, or with MS's compilers).
The architecture also uses an “event-driven system” for the main game loop.
Sorry about the restrictive license, but that's because it's rough, unfinished, and for practice and not really serious work. I hope you understand.
Now, the questions:
There is a “renderWorld” routine in the WorldManager, which doesn't seem right – this is related to rendering... where should it be? It needs the data from the world to render it (entities, map, etc.). I also heard at
http://www.gamedev.net/topic/618973-creating-a-render-manager/#entry4905254 that a graphics system should only take in basic graphical objects and not more sophisticated objects like entities or “models”, etc. (the linked post says: “Likewise, a model has no place within the graphics module. (...) a general theme is that the graphics module simply handles the commands needed to render things, and provides wrappers for textures, vertex buffers (...)”). The RenderManager works in just that way: the primitive objects it receives (RenderObjects) store simple graphical representations (here grids of characters) only. Yet something has to get that lower-level data (in this case, ASCII representation, in that case, triangles/textures/etc.) from the higher-level entity/map objects and feed it into the render/graphics system: what should it be?
There is a reference to the input manager in the player's “AI component”, which is needed because for the player entity to make decisions when its it's turn to act, it needs a command from the user. But it doesn't seem right it should “know about” the input system, does it? If not, then does that mean we should add more code to the event handler to check if the acting entity is the player entity and capture the input there and then pass it on to the entity, thereby avoiding the reference to the input manager but adding more complexity/specialization in the event handling system? But if that's bad too, where should we put the calls to the input manager (remember: we don't want input until the player's “turn to act” comes around, i.e. when the EVT_ENTITY_ACTION event with the actingEntity variable equaling the player entity is due)? Already we have a problem in that the “quit” command isn't really something the entity does, but a signal to the game to stop!
Where should the handler for game events go? Not all events (EVT_QUIT is an example – there'd be others in a real game) involve an entity acting. So putting it on the entities doesn't seem to work – or should one have handlers for those kind of events on the entities, and handlers for the other in the game? But would putting it on the entities violate the component system? If so, what should we do? Have something to translate events to messages?
Also, how would one make the part of the program that handles stuff like collisions/interactions between entities, with tiles on the map (right now, there is no collision handling and I only have an “ad hoc” stop in there (clearly marked!) to keep the player from running off the map altogether! Obviously that is a big no-no in a production program! It's just a placeholder until I can get how to work this out.), etc.? It doesn't seem right to make the physic component of an entity have full access to the map and all entities on it (i.e. essentially the whole WorldManager), does it? If it isn't right, then what should I do (that “ad hoc”-marked code is really just a placeholder because I'm not sure how to handle this dependency problem)?
And in a bigger game, where you can pick stuff up, what's the best way to distinguish a “pickupable” entity from a non-pickupable one?
I'd also like to hear a general review/comment/critique/etc. of the code – any pointers for improvement would be welcome.