Jump to content
  • Advertisement
Sign in to follow this  
swiftcoder

Structuring a game engine

This topic is 4160 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am having an interesting time - to say the least - with the structure of my game engine. Initially I modelled the engine several graphics engines (IrrLicht, Ogre...), and created a monolithic scene-graph which handled scene-hierarchy, culling, render batching, animation and physics. As most of you who have tried this probably know already, past a certain point this just doesn't work. So now I am trying a 'distributed' approach (please forgive my terminology problems). I am now using the scene-graph solely for parent-child relationships between nodes, and each node holds various 'chunks' - for lack of a better word - which give it substance in the game world. Chunks are for things such as geometry, physics, AI and sound. Ideally, each type of chunk would be managed in its own unique structure, but in fact this seems hard to do. Here is my problem: every type of chunk in the system needs to share some data, but for modularity, I wanted to keep each largely unaware of how the others are implemented. For instance, of the 4 chunks I enumerated above (geometry, physics, AI and sound), all are going to need to know object positions, the last 3 (at least) will need to know about movement/velocity, and all except possibly AI are going to need to do some sort of culling for performance purposes. And the organisation for each type of chunk has to be radically different... Geometry and sound are fairly flexible, but both need to be organised by some notion of spatial locality. AI needs to be organised by various methods - maybe by faction and unit groups, and Physics needs to be organised by joints, etc. ATM I have a class for each type of chunk, instances of which are help by nodes in the scene graph. When you add a geometry chunk, for instance, it, must also be added to the current culling manager, and for physical objects it must be added to the physics subsystem... The problem is that some shared data, namely position and motion information, is needed by all subsystems, and has thusly been placed in the node class. This means that now all of the chunks have to know about the existence of the node class, in order to get/set these variables. There is also an issue of which subsystems are allowed to write to each variable: it is documented that only the physics system can write to the position, but I want some way to enforce this. So I guess what I wanted to ask is ultimately - how do you deal with this in your own code? Some sort of pointers to how best to organise this sort of partially-related data would be good.

Share this post


Link to post
Share on other sites
Advertisement
Quote:

Original post by swiftcoder
it is documented that only the physics system can write to the position, but I want some way to enforce this.


Sorry if this seems dumb (I have zero experience with scene graphs), but how about this:



class PhysicsChunk {
public:
void setPos(Vector3 &pos) { // ... }

// ...
};

class Node {
public:
void setPos(const PhysicsChunk &pc) {
pc.setPos(mPos);
}

private:
Vector3 mPos;
};




Also, have you looked here?

Share this post


Link to post
Share on other sites
Hmm... I'd do the following:

- abstract base class "Spatial" with abstract getters and setters for velocity/position
- Node as a subclass of Spatial which implements the setters and getters by direct variable access
- Two subclasses SpatialWrapper and ConstSpatialWrapper of Spatial which delegate the setters/getters to a "Spatial&" and "const Spatial&" respectively.
- PhysicsChunk would be a subclass of SpatialWrapper, while AudioChunk would be a subclass of ConstSpatialWrapper.

But I think there's another problem with your system: Maintaining the integrity of the containers. I.E. if the node is discarded, then its AudioChunk, PhysicsChunk, etc. must be removed from their respective containers. I don't know of an easy and elegant way to do this in C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Also, have you looked here?

Nice resource there, I have bookmarked it. Unfortunately most of those take the monolithic approach (everything and its brother in one tree), and I - as have many others - have found this system to be far to limiting. There is definitely some good information though.

Quote:
Original post by Barius
But I think there's another problem with your system: Maintaining the integrity of the containers. I.E. if the node is discarded, then its AudioChunk, PhysicsChunk, etc. must be removed from their respective containers. I don't know of an easy and elegant way to do this in C++.

Currently each 'chunk' knows how to remove itself from its own container structure, and does so when it is removed from the node. This is not ideal though, as each chunk must hold some sort of iterator-like pointer back into its container.

[Edited by - swiftcoder on July 26, 2007 9:46:47 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Barius
Hmm... I'd do the following:

- abstract base class "Spatial" with abstract getters and setters for velocity/position
- Node as a subclass of Spatial which implements the setters and getters by direct variable access
- Two subclasses SpatialWrapper and ConstSpatialWrapper of Spatial which delegate the setters/getters to a "Spatial&" and "const Spatial&" respectively.
- PhysicsChunk would be a subclass of SpatialWrapper, while AudioChunk would be a subclass of ConstSpatialWrapper.


Hmm, I like that. If the wrappers are moved into their own inheritance tree, then we can use composition, rather than inheritance, which would work nicely.
One of the goals I am trying to achieve is a clear separation between the hierarchical organisation of the scene-graph, and the optimised organisation of the geometry and physics graphs. Overall, I *don't want* any of the chunks to derive from the same base as the node (spatial in your example), as it makes it harder to separate out the various subsystems.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!