Engine approach

Started by
18 comments, last by Structural 20 years, 6 months ago
A question for those of you who have written a game engine: How do you approach your engine from your code? - Do you use a message system? posting messages to the engine, then the engine evaluates to which component the message is supposed to go. Also the engine approaches the game through the same message system. Basically you get an event driven engine. - Do you have a load of public functions that drive the engine? For example OpenWindow, or LoadModel. If so, can your engine give events to the game, or does the game have to poll for changes? - Is your engine completely script driven? You could also use scripts to control your engine. Load keymaps, or resources through a script file. The reason I''m asking is because I''m now working on a personal project that uses the message driven approach. The problem is that the number of messages is huge and I have several different message structures (though in the message handler they are all represented as a single block of data). I have messages for creating menu components, to create windows, to notify the game of mouse and keyboard input, to add models, etc etc. And I need several lines of code to fill a message structure with correct data and post it to the engine. I have the feeling I have to write more code to get the same thing done. So, tell me, what is the best approach? And how (if possible) can I make my code more efficient (in the sense of coding)?
STOP THE PLANET!! I WANT TO GET OFF!!
Advertisement
Now, while I haven''t completed an engine per say, I''ve often struggled with this very question.

Personally, I found the message system too much of a hassle. Sure, it makes for some nice decoupling of systems, but the overhead doesn''t seem worth it.

It seems to me most professional engines don''t use message passing (unless I''ve been reading the Homeworld source all wrong) ...

- Ben
- Ben
Same here. I''d be interested in hearing some different approaches on this subject also.

I know only that which I know, but I do not know what I know.
My engine (which isn't finished), is arranged into modules where each main part of the engine has it's own class. Kinda like this (simplified, of course):

                              CGame                                |      -----------------------------------------------------      |             |           |           |             |  CGraphics      CInput      CSound      CObject      CScripting      |             |                       |             |   Render()     GetInput()                CMesh       LoadLevel()SetupMatrices()   SInput                  CLightSRenderingPackage                        CTerrain


So basically, a CGame object it created, which creates and manages all the objects in a set order. Like it gets input, scripting, then goes to AI, then sound, and then renders.






[edited by - circlesoft on October 8, 2003 5:55:31 PM]
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
This is something I have been struggling with recently myself, and I have been trying over and over to come up with something cool that requires minimal effort to layer a game on top of it.

I guess you could say I am looking for something 'elegant'

Right now, my CGame class calls several member functions to init the required systems (D3D,DI,DS,etc), which are kept track of by member vars inside CGame, and then from there, I use a pointer to a game state object, which is a hierarchy off a base game state class, ... so each gamestate I make knows how to update/render itself... but I have to pass in the d3d device to each of these everytime I create it, which seems useless... or inelegant. I can't think of a nice way to tie together the subsystems.

Ok, I'm gonna stop rambling since I can't seem to collect my thoughts.. seems to be what happens when I try to think of how I should really make the engine.

I just don't see the whole picture yet.




------------------------------------------------------------
// TODO: Insert clever comment here.

[edited by - drowner on October 8, 2003 1:40:53 PM]
------------------------------------------------------------// TODO: Insert clever comment here.
@CircleSoft:
Yes, but how does it communicate with the rest of the game?

I also have a modular design, with modules that can be compared to those of you. Each is derived from CTask and are managed by a task manager, which is no more than a loop that calls their update() function each cycle.
But the big question is, how do I get my data into the engine? And how do I get my engine data to my game?
The message approach is good for a generic approach. You use the same message type for each module. But the big disadvantage is that there is no option to request data from the engine the moment you need it.

For example:
Game wants to know the position of somesort of object
Game: Post message to the engine to get the position
Engine: finish cycle
Engine: Once the object manager is update()-ed the manager posts a message to the game about the position
Engine: Launch some more update()'s, untill it launches the games update
Game: Retrieve messages, and then get the position of the object.

Also, you need tonnes of lines of code to actually prepare a message to be posted.

Ofcourse, you could use pointers to point to the object directly, but then you require the game to actually know the classtype of your object.


Someone else poked me with an idea of how to get data on request. Perhaps you can use function pointers (passed through the message system on startup) to call certain functions, like getPosition() (for example). You don't have to know the object type then and you can still call it.

However, this all seems a lot of hassle to me to use a message system AND a function pointer system. This defies the idea of having one genric method of approach.

Oh, oh... and another idea just popped up. Perhaps you can write a conversion layer that simplifies the message posting. Then you can still keep the message system for commands that are not used very much, and use the conversion layer to post frequently used messages (like enabling/disabling menu items for example).

So many ideas spinning around in my head, and no clear view of what is the best.

[edited by - structural on October 8, 2003 1:40:35 PM]

[edited by - structural on October 8, 2003 1:42:17 PM]
STOP THE PLANET!! I WANT TO GET OFF!!
If you look under CGraphics in my diagram, you see one SRenderingPackage. This is essentially one very large structure that contains vectors of all the object types. There is one vector for generic mesh objects, another for water objects, terrain objects, lights, and so on. The base SRenderingPackage is a member in CGame. The renderingPackage is populated when the level is loaded. A pointer to it is passed to CGraphics, which loops through every object, culls them, and then renders.

This whole idea of a structure that encompasses all the objects and then can be passed to each module (if they need it) allows all the realtime info that is needed to be shared.

I hope that makes a little bit of sense




[edited by - circlesoft on October 8, 2003 5:55:44 PM]
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
As for finding information in one class like: the video, that needs to know a value of something in the scripting class just to say. You could use a pointer in the indivual modules that points back to the CGAME class and basically allowing you to query whatever you may want inside the CGAME and it''s modules. I''ve done something similar, but I always seperated the modules,

I don''t know why, but I never thought of putting the modules inside the game class itself... it makes so much more sense. Thanks circlesoft.

I know only that which I know, but I do not know what I know.
I have just started designing an simple engine as a learning project, it will most likely by a message based system.
There are some more overhead, but it will be very flexible and also easier to debug (just dump all messages). It also makes networking more easy, and since this is a multiplayer engine that is a big plus.
quote:Original post by circlesoft
If you look under CGraphics in my diagram, you see one SRenderingPackage. This is essentially one very large structure that contains vectors of all the object types. There is one vector for generic mesh objects, another for water objects, terrain objects, lights, and so on. The base SRenderingPackage is a member in CGame. The renderingPackage is populated when the level is loaded. A pointer to it is passed to CGraphics, which loops through every object, culls them, and then renders.

This whole idea of a structure that encompasses all the objects and then can be passed to each module (if they need it) allows all the realtime info that is needed to be shared.

I hope that makes a little bit of sense


I think I see your point.
So you see your top-level modules as managers for the lower-level modules. But the game can still access the lower-level modules to perform operations on them.
So, in case of your CGraphics module, it manages the render package. It draws it to the screen.
But your game also knows about the renderpackage and can populate it.

That''s quite interresting. Leave the full hierarchial (spelling?) model and use a combination of hierarchy and all-know-all.
Hierarchy between the CGraphics and Rendering package
All-know-all between the game and rendering package.

Feel free to correct me if I''m wrong, but I like that idea!
STOP THE PLANET!! I WANT TO GET OFF!!

This topic is closed to new replies.

Advertisement