   Having trouble with the big picture (architecture)
  So I've been working on a new game since the end of December, but it's gotten to the point where I can't bring myself to work on it because the code has grown too much and I can't see how to tame it without massive refactoring, so I'm going to rewrite the thing - hopefully with better planning. (I've already tried a pretty major partial-rewrite - that just made things worse, so I rolled the code back)So, I'm hoping for some pointers and insight with how to design the architecture of the game. The place where my project breaks down is communication between unrelated objects.I am currently using a component based design, where every object ingame inherits several different components, and each component manages itself. Example:class Ship : public GraphicComponent, public LocationComponent, public UpdateComponent, public InputComponent{    //Implement virtual 'GraphicComponent' function.    //Implement virtual 'LocationComponent' function.    //Implement virtual 'UpdateComponent' function.    //Implement virtual 'InputComponent' function.};Each component, depending on what it does, has a associated 'manager' with it. For example, 'GraphicComponent' registers itself automaticly with a global of type 'GraphicManager', and that GraphicManager is called when it's time to draw, and draws every GraphicComponent on the proper layer.It was working very well for me, I could quickly create new entities with ease, so I'd like to continue to do something similar, but I have a few problems with it.First, it doesn't make logical has-a/is-a sense. The way I currently have it, a 'Ship' is-a 'GraphicComponent', a Ship doesn't have-a GraphicComponent. That might just be my naming scheme, though.Second, some components need to share the same data. I want every Ship to have a unique ID, but more than one component needs access to that ID, so I'll need to pass it in to that component's constructor. That seems... clumsy - especially if I ever need to pass in more than just an ID (like say, the Ship's location).Third, I'm at a loss how to get multiple different entities to interact with each other. I haven't implemented collision yet, and I'm a bit aprehensive of doing that with this system. How can I get different entity types to interact with each other, like if one shoots another, or when I need to implement AI which needs to 'see' nearby ships, or something else?How do you recommend I restructure my code? My primary concern is communcation of completely unrelated entity types, while still allowing me the flexabillity and speed of creating new entities by dropping in components and filling in a few functions.   
  Well, firstly I would recommend using a 3rd party collision detection system: PhysX, Bullet, etc.  CD is super hard to get right and performant and multi-threaded.  Better to not waste your time implementing one unless you're in it for the challenge.The component model is a good idea, typically it's all has-a relationships so you can compose entities by slapping together a bunch of components.  Very few components should need access to other component data if you have your model nice and tidy.  I'm not sure of a clean architecture for components to access other component datas.  Maybe some sort of listener model where the wiring is hooked up by the composing entity: physicsComponent->addListener(aiComponent) where aiComponent extends the physicsListener interface or something?That all said, you said you were working on a "new game" but it sounds like you are working on a "new engine".  Have you taken a look at existing engines to see if they are suitable for your game?  Putting together a solid 3D engine is a multi-year process even for a relatively large team.  Putting a game on top of that is another year or more.  If you're not interested in actually building an engine it might be beneficial to just skip to the make a game part by using an existing engine.-me   ;  Yikes, you have a lot going on here, and i think your inheritance is a bit of overkill.First of all, the ID's.... your Engine should have some sort of assetManager that keeps track of your objects, usually allocating a pool of memory and then when your game needs an object of a certain type it grabs it from the pool. THAT i will leave for you to go figure out on your own (google it).secondly, collision, a great post about collision reports and such is http://www.gamedev.net/community/forums/topic.asp?topic_id=482784there.... kudos to MJP for a rather straight forward explanation. (that is how physx does it but honestly thats a great way of doing it).however.... notice how your declaring properties of your entity AS inherited classes. graphics component and update sure, that seems okay i guess (I just have a RenderComponent* RC pointer that each object has to point to how to render whatever mesh or particle or thing it has (in my simple case, just a mesh and texture (and normal map), But you should not get carried away with it. First... lay out what you want your ship to do, does it need to fly around? does it need to shoot at other stuff? does it collide with other stuff? Try to figure out just how this ship is going to function and go from there. Maybe the actual ship doesnt need to worry about colliding with stuff, but its bullets need to collide with stuff, etc. This is called Top-Down design, and it helps you fill out the big picture of things a little more.   ;  Unreal engine has a lot of components much like you do.However, instead of classes inheriting their components, unreal engine objects contain a list of their components and they get looped through to get a Tick() function etc.So, the path you are going isn't without precedent but the way you are implementing it might be!   ;Quote:Original post by PalidineWell, firstly I would recommend using a 3rd party collision detection system: PhysX, Bullet, etc.  CD is super hard to get right and performant and multi-threaded.My collision detection would be simple Axis-Alligned squares, and possibly non-axis-alligned ones. Nothing fancy. I considered using Box2D for it, and I may still go that route, but I figured it'd actually be easier to look up a simple tutorial on non-axis-alligned collision, then a tutorial on using Box2D. (I don't need the physics part, just the collision)Quote:The component model is a good idea, typically it's all has-a relationships so you can compose entities by slapping together a bunch of components.  Very few components should need access to other component data if you have your model nice and tidy.Yea, very few components do need to access shared data, but it comes up on occasion.I've tried 'has-a' components, and it makes more sense for components, but the problem is, it massively increased the amount of code I needed to write. With my 'is-a' version, 'Ship' inherits GraphicComponent, and implements GraphicComponent's virtual function 'Draw()'. A different entity, say, 'SpaceDebris', uses the exact same GraphicComponent class, and also implements the virtual function 'Draw()'. All a new entity has to do, is fill in the virtual function for whatever components it inherits.With my 'has-a' attempt, I had to make the components abstract, and have personalized components for every entity! Instead of 'Ship' inheritting 'GraphicComponent', I had to have 'Ship' inherit 'AbstractEntity', and Ship contain 'ShipGraphicComponent' which inherits 'AbstractGraphicComponent' which inherits 'AbstractComponent'. Then 'SpaceDebris' would need it's own personalized 'SpaceDebrisGraphicComponent', as well as any other entity I would want to add.(In retrospect, I was probably doing it wrong... 'GraphicComponent' should be passed the sprite, so it doesn't need to be unique to every entity)Quote:I'm not sure of a clean architecture for components to access other component datas.  Maybe some sort of listener model where the wiring is hooked up by the composing entity: physicsComponent->addListener(aiComponent) where aiComponent extends the physicsListener interface or something?Sounds interesting. But how do I pass information about events and entities? How do I know what the Ship crashed into (was it an asteroid or a bomb?), and at what speed? And how do I pass messages between entities?Quote:That all said, you said you were working on a "new game" but it sounds like you are working on a "new engine".  Have you taken a look at existing engines to see if they are suitable for your game?  Putting together a solid 3D engine is a multi-year process even for a relatively large team.It's 2D, actually. I have a tendency to bite off more than I can chew - and I'm trying hard not to this time. My previous completed game was a 2D TBS space game, so this time around, I'm making a 2D real-time wing-man style space game. Just trying to go only a few steps above my previous project, so I don't overreach myself. My previous project was clunkily put together, and I want my new project to help me grow in coding good/clean code.As I read your post and typed this one, I think my problem is I'm not making my components generalized and specific enough. GraphicComponent should be so generalized for classes by being specific at what it does - Why should entities need to implement virtual functions for it? It should have one draw routine... for drawing a sprite. Entities can pass it which sprite to draw, I don't need to overwrite it's draw function for each entity. I'm still at a loss for message handling. Maybe create a 'MessageComponent' with a queue of messages, and the entity that owns it, polls the queue each frame?   ;linki guess you want it easier than copy and paste? http://www.gamedev.net/community/forums/topic.asp?topic_id=482784   ;Quote:Original post by Servant of the LordI am currently using a component based design, where every object ingame inherits several different components, and each component manages itself. That's your problem right there imo.You might think you're getting behaviour for free and doing less typing and stuff, but this mega-inheritance (as I call it) just leaves you in a state where you daren't touch anything.I suggest seriously thinking again about your implementation here and maybe code one type of object at a time. Or at least break up the inheritance into one or two key things.There's just no need to inherit a class to pick up a couple of variables.;  Thanks for reposting the link, AverageJoeSSU. I dimissed the article the first time (after a casual glance), thinking you thought I was making a 3D game. [smile] Now I see you were talking about the communication method PhysX uses. Very interesting, and definitely worth some thought on my part - I can imagine that working quite well in my situation.   ;Quote:Original post by RubiconYou might think you're getting behaviour for free and doing less typing and stuff, but this mega-inheritance (as I call it) just leaves you in a state where you daren't touch anything.Unfortunately, yes, that's what's happening.Quote:I suggest seriously thinking again about your implementation hereI am, hence this thread. [wink]"gotten to the point where I can't bring myself to work on it because the code has grown too much and I can't see how to tame it without massive refactoring, so I'm going to rewrite the thing - hopefully with better planning."Quote:and maybe code one type of object at a time. Or at least break up the inheritance into one or two key things.Could you explain that a bit more? You're saying, have one or two classes I inherit from, like an 'AbstractEntity', and a 'PhysicalObject' entity, for a Spaceship?What do you mean by code one type of object at a time? Do you mean, make sure Ships are working before adding Missiles, or do you mean make sure Rendering is working before adding Physics?Also, are you discouraging the use of component-based design, or just my flawed implementation of it?Quote:There's just no need to inherit a class to pick up a couple of variables.They were inheriting, not for variables, but for virtual functions. Not much better, I admit, which is why I said in my original post, I would rather they weren't inherited by the entity, but members of the entity - I'm just unsure how to do it.;Quote:Original post by Servant of the LordThanks for reposting the link, AverageJoeSSU. I dimissed the article the first time (after a casual glance), thinking you thought I was making a 3D game. [smile] Now I see you were talking about the communication method PhysX uses. Very interesting, and definitely worth some thought on my part - I can imagine that working quite well in my situation.no problem. I have to admit what you are doing is very different from how i have things organized (i am using lua and C++ and you are going straight C++), so my arch. is designed in such a way that i provide an API.so "Ship" is defined at the scripting level for me.But the physx interaction is very fundamental and pretty straight forward actually.   