Sign in to follow this  
johnnyBravo

Could people show me their game class layouts?

Recommended Posts

Hi, I'm trying to decide on how to layout my game classes for the 100th time. And I was wondering if people could post their header files or give a brief description on how the classes are layed out. I want to see what other people are doing, because I've got a few ideas, but they seem not to work very well as my games get larger and more complex. I've been recently looking at Directed Acyclic Graph classes (DAG) which seems like a good idea, which basically is a layout where there are no loops in the class connections. eg it can't have connections like: class A depends on class B class B depends on class C class C depends on class A My problem with this is how to represent it at a code level. Should I have all the classes global? or in each class actually put pointers to the other classes where the connections exist (which doesn't seem very flexible if i am to want to remove or make new connections to existing classes). Thanks.

Share this post


Link to post
Share on other sites
The thing is, "depends" isn't very descriptive.

Some places you might need B to inherit from A, other places you'll need C to have instances of B and/or A.

Share this post


Link to post
Share on other sites
You may create a pure virtual class which has one function such as ProcessMessage (Message) and all other classes are derived from it. When one object wants to connect to the other objects, it calls their ProcessMessage () functions with the appropriate message along.

It seems to be more object-oriented I think, while objects tell each other what to do or ask them for infos. But I use it sparingly as it is more complex than the original method.

It may help solving your problem though, give it a try.
Hth
V@T

Share this post


Link to post
Share on other sites
I use DAG's for mine. It's fast and easy.

Basically all my game objects inherit from a single base abstract class: GameObject.

It has a Notify method that takes a GameEvent object. Each GameEvent has a Type (BROADCAST, COM, MOVE, CUSTOM, etc) Using the event object, each GameObject checks to see if it has any EventResponse's registered for that type of event. If so, it returns them and they get put in a list. Then Notify gets called on each child, appending their EventResponse's to the list.

After all this, the EventResponse's are sorted by their priority field and then sent off to the scripting engine to be executed.

Share this post


Link to post
Share on other sites
Crazy ideas - never thought about it.

Mine is more simple, because I have only made simple games.

I'll have a class similar to gameObject for example.


Inside it will have 3 functions

input();
think();
draw();


input will call think
think will call draw
draw will call input

Share this post


Link to post
Share on other sites

  • Everything is separated into local, global and avatar categories.

  • Local objects and avatars are stored and manipulated on the client, and do not exist on the server. Global objects exist only on the server, but are available as read-only proxies to the clients. Local controllers can be used to send orders to global objects from a client.

  • There is no such thing as an "update step" to most of the system. Also, except for avatars, no part of the system is aware of "frames" (since only avatars may be rendered).

  • The biggest unit of organization is the World. Each world has an unique global space-time. Space (physics, collisions) is managed by a physics module while time is managed by a scheduling module. Each world also has a local rendering space in which the avatars for that world are rendered on the client.

  • Everything is expressed in terms of initial state, start time and evolution. Current information is never used, which makes server/client communications much easier. Server-to-client latency is solved without backtracking simply by changing the above data.

  • Client-to-server latency is solved by having the client issue commands into the future, delaying commands that were meant to happen before they were received (and allowing batches of commands, so such batches are always executed in the same order), and also giving the server enough liberty to actually backtrack to a previous state to see what the result of a command would be, and accept it if it does not interfere with other commands.

  • Scheduling means providing a function that will be called after a certain time has elapsed. Scheduling can be global (and occurs exclusively through local controllers) or local (at which point it can only affect local objects or avatars). Nanosecond-level precision is ensured as far as global and local objects are concerned. Avatars only have a 60Hz guaranteed precision, but the precision error that occurs below that treshold will usually be unnoticed.

  • Each object has access to the world it appears in (and also to all modules owned by this world, such as collision detection, rendering, client-side resources or scheduling). Scheduling is performed in an idiomatic way. Aside from this, there should never be such things as singletons. Each object can only manipulate objects which it created, which were given to it in any way.

  • Where are objects stored? Usually on the heap, with an appropriate allocator. There are no "list of all objects" managers, although modules may keep internal lists (such as an event queue, a tree of avatars in a scene graph or a synchronization module). Most objects are not owner or pointed to by anyone, except maybe a garbage collection system and one or more scheduled operations that will be applied to them.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endar
The thing is, "depends" isn't very descriptive.

Some places you might need B to inherit from A, other places you'll need C to have instances of B and/or A.


Yes I am beginning to see that.

I've been trying to decide on whether the rendering of each object, the sky, particles, and the menu should all reside in the render class, where the render class can see all the entities that it should render,

or should each entity have a pointer an adjacent Drawble class that is stored in some arrays sitting inside the render class which tell the render class the position to draw, use what textures etc.

Or should I have seperate classes each to render all the objects, the sky, all the particles?

Quote:
Original post by Skeleton_V@T
You may create a pure virtual class which has one function such as ProcessMessage (Message) and all other classes are derived from it. When one object wants to connect to the other objects, it calls their ProcessMessage () functions with the appropriate message along.

It seems to be more object-oriented I think, while objects tell each other what to do or ask them for infos. But I use it sparingly as it is more complex than the original method.

I don't know if I want to go into using messages right now, although they look quite good if used properly, but I'm sure theres going to be some unforeseen design problems that I haven't thought about.
Also theres the problem with too tightly coupling the classes where I am unable to modify something without causing problems elsewhere.

Quote:
Original post by AfroFire
Crazy ideas - never thought about it.

Mine is more simple, because I have only made simple games.

I'll have a class similar to gameObject for example.


Inside it will have 3 functions

input();
think();
draw();


input will call think
think will call draw
draw will call input

Hmm seems kinda funny ;)

Like some kind of function loop?

Quote:
Original post by ToohrVyk--

I'll remember that the next time I create a mmorpg :), i think some of this is way above my head. The hard part for me is trying to make every come to together seemlessly.

Thanks guys, all this game class design is pretty complicated..

Share this post


Link to post
Share on other sites
Quote:
Original post by LordShade
Some form of message queue will solve a ton of interdependency issues.


True, but there is a fair amount of coupling assumed in using messages in that form.

My class layout is as follows, and it does use messages for input.

There is a system class which knows about all of the subsystems such as: InputManager, RenderManager, PhysicsManager, GuiManager, GameManager, ResourceManager, SoundManager, ScriptManager, etc.

Most of these managers maintain lists of objects which inherit specific interfaces. InputManager registers InputListeners. RenderManager registers Renderables, PhysicsManager registers WorldEntities, GuiManager registers Screens, and so on.

InputManager queries DirectInput each frame and dispatches input to the InputListeners. GameManager and GuiManager inherit InputListener. They receive input every frame. They process the input and perform actions based upon the InputMessage received.

Screens and GameEntities inherit Renderable. RenderManager renders them each frame.

GameEntities also inherit WorldEntity so they are acted upon by the PhysicsManager each frame, but before they are rendered.

System is responsible for creating each of these managers and passing to them the specific data that they need to initialize. It then enters the main game loop which does the usual:

Input - Dispatch all input
Process - Update states and physics
Render - Render the frame

Most of the Managers need to know about specific Managers such as the ResourceManager so each of them will have a pointer to the instance of ResourceManager which should be creating their resources. No singletons here, instead, that pointer is added to the SubSystem interface as is a pointer to any other manager that will be needed my most SubSystems.

That's my layout in a nutshell. I have not completed a full game yet, so take this all with a grain of salt.

Share this post


Link to post
Share on other sites
It doesn't have any member method / properties descriptions, but here's my overall design:

http://www.mike-n.com/stuff/go.png

Where classes above the line are 'system' classes, below that are actual game object types

The basic underlying idea is that an Object can receive actions; only Actors can perform actions.

Share this post


Link to post
Share on other sites
Thank you dragon, I appreciate that. I also am looking for how others ( who no doubt have had to do much research as I have just to get an understanding of how all classes should be grouped ). Its very difficult to to get a nice broad view of how everything should plug into and derive each other when there is so much involved.

and if anyone wants to do similar, i think others (including myself would benefit).

thx,
-sd

Share this post


Link to post
Share on other sites
For a little columns game I wrote a little ago:

<inherit>
renderable ----> game
||
<contains>
||
|| <inherit>
renderable ---->playfield <---- timed
|| ||
<contains>
renderable --> brick piece
||
<contains>
|| || ||
brick brick brick


That's just the game part. There's tons of other stuff to handle input, render stuff, do menuing...

Share this post


Link to post
Share on other sites
Quote:
Original post by blackdot



Most of these managers maintain lists of objects which inherit specific interfaces. InputManager registers InputListeners. RenderManager registers Renderables, PhysicsManager registers WorldEntities, GuiManager registers Screens, and so on.

InputManager queries DirectInput each frame and dispatches input to the InputListeners. GameManager and GuiManager inherit InputListener. They receive input every frame. They process the input and perform actions based upon the InputMessage received.

Screens and GameEntities inherit Renderable. RenderManager renders them each frame.

GameEntities also inherit WorldEntity so they are acted upon by the PhysicsManager each frame, but before they are rendered.

System is responsible for creating each of these managers and passing to them the specific data that they need to initialize.



This is the kind of layout I have been thinking about.

But what kind of data would be in the rendable class? eg would there be a mesh, or would it just have a pointer or index integer so the renderManager knows what to use?

And I am also leaning towards using a scene graph(which is just a bunch of nodes i think..). So how would that come together with the entities inheriting the rendables?


Quote:
Original post by RDragon1
http://www.mike-n.com/stuff/go.png

Where classes above the line are 'system' classes, below that are actual game object types


So the weapon's axe and sword are not seperate classes, but just instances of the Weapon class?

Thanks!

Share this post


Link to post
Share on other sites
Quote:

So the weapon's axe and sword are not seperate classes, but just instances of the Weapon class?


No, they are classes as well. Each game class gets registered into a factory, and that is used to create any object. "Default properties" are implemented as virtual functions, as such:


sample:

class Weapon
{

public:
virtual unsigned short damage_upper() const = 0;
virtual unsigned short damage_lower() const = 0;
};


class Sword : public Weapon
{
public:
virtual unsigned short damage_upper() const { return 2; }
virtual unsigned short damage_lower() const { return 1; }
};

class Axe : public Weapon
{
public:
virtual unsigned short damage_upper() const { return 3; }
virtual unsigned short damage_lower() const { return 1; }
};


class SuperAxe : public Axe
{
public:
virtual unsigned short damage_upper() const { return 5; }
virtual unsigned short damage_lower() const { return 10; }
};


...

Weapon* some_weapon = factory.create( "axe" );
std::cout << "damage range is " << some_weapon->damage_lower() << '-' << some_weapon->damage_upper() << '\n';



Some people call this "virtual static" because the properties are stored once for each class, but it allows derived classes to override the values (properties) of the object.

Share this post


Link to post
Share on other sites
Quote:
Original post by johnnyBravo

This is the kind of layout I have been thinking about.

But what kind of data would be in the rendable class? eg would there be a mesh, or would it just have a pointer or index integer so the renderManager knows what to use?

And I am also leaning towards using a scene graph(which is just a bunch of nodes i think..). So how would that come together with the entities inheriting the rendables?



The way I was considering doing it was to have one instance of each model in memory. I would be doing quaternion based animations, so the actual animation would be calculated out for each character each frame. I am not stuck to this, so I may go another route. A Renderable would have a pointer to it's model. It would have some animation specific information. ResourceManager loads the instance of each model being used. When the character (Renderable) is loaded, it is given a pointer to the model that represents it.

Again, since this is my first game, I may find that this will change, but I think you have the idea of where I am going with this. The scene management part is still up in the air for me. I was also considering having a Scene Graph. As a result, the RenderManager may not directly deal with Renderables, but instead deals with a Scene Graph. I will come back to you after I have thought about it. :) I also am working specifically with D3D so I am not making a generalized rendering system.

Share this post


Link to post
Share on other sites
Quote:

But what kind of data would be in the rendable class?


None. Or rather nothing that you're thinking of [imo]. Renderable for me is just an interface, which allows me to inherit from that to make actual rendering classes [like image, text, and more complex classes like the game objects]

Quote:

So how would that come together with the entities inheriting the rendables?


Since it's just an interface, you can then arrange all of the renderables together, and the graph just calls render() for each. They then can handle the details.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Quote:

But what kind of data would be in the rendable class?


None. Or rather nothing that you're thinking of [imo]. Renderable for me is just an interface, which allows me to inherit from that to make actual rendering classes [like image, text, and more complex classes like the game objects]

Quote:

So how would that come together with the entities inheriting the rendables?


Since it's just an interface, you can then arrange all of the renderables together, and the graph just calls render() for each. They then can handle the details.


What graphics API are you using? With Direct3D this sort of approach would necessitate that each Renderable object would have a pointer to D3D or have a pointer to an object that wraps around D3D. This is alot of potential overhead.

Also, suppose you did want to change rendering libraries for whatever reason, would you have to rewrite the render() function in each Renderable?

Just curious as to how you would approach that.

Share this post


Link to post
Share on other sites
Quote:
Original post by blackdot
Quote:
Original post by Telastyn
Quote:

But what kind of data would be in the rendable class?


None. Or rather nothing that you're thinking of [imo]. Renderable for me is just an interface, which allows me to inherit from that to make actual rendering classes [like image, text, and more complex classes like the game objects]

Quote:

So how would that come together with the entities inheriting the rendables?


Since it's just an interface, you can then arrange all of the renderables together, and the graph just calls render() for each. They then can handle the details.


What graphics API are you using? With Direct3D this sort of approach would necessitate that each Renderable object would have a pointer to D3D or have a pointer to an object that wraps around D3D. This is alot of potential overhead.

Also, suppose you did want to change rendering libraries for whatever reason, would you have to rewrite the render() function in each Renderable?

Just curious as to how you would approach that.


Wouldn't you want to inherit CDirectXRenderer and COpenGLRenderer from IRenderer, in which case all you have to do is fill out functions for your new renderer?

Share this post


Link to post
Share on other sites
Quote:
Original post by blackdot
Quote:
Original post by Telastyn
Quote:

But what kind of data would be in the rendable class?


None. Or rather nothing that you're thinking of [imo]. Renderable for me is just an interface, which allows me to inherit from that to make actual rendering classes [like image, text, and more complex classes like the game objects]

Quote:

So how would that come together with the entities inheriting the rendables?


Since it's just an interface, you can then arrange all of the renderables together, and the graph just calls render() for each. They then can handle the details.


What graphics API are you using? With Direct3D this sort of approach would necessitate that each Renderable object would have a pointer to D3D or have a pointer to an object that wraps around D3D. This is alot of potential overhead.

Also, suppose you did want to change rendering libraries for whatever reason, would you have to rewrite the render() function in each Renderable?

Just curious as to how you would approach that.



I'm using D3D currently.

As for the first point, I set a 'context' on entry to rendering [and occasionally thereafter in the rendering process] which wraps the actual pushing bits to buffers. The context is merely a global. It could just as easily be a static renderable member, or singleton. No great overhead there.

Further, it's not that big a deal, because in reality, only two classes that inherit from renderable [that aren't contexts] actually interface with that context currently. Image and Text. Everything builds off of those two building-blocks [and non-D3D renderers like timers]. So to switch to OGL, I would need to re-impliment only those two classes, create new context classes to push bits to OGL buffers, and re-impliment some helper stuff like image loaders.

Since the rest of the renderables deal with images and text though those classes, they can effectively ignore the implimentation, and work without modification.

Share this post


Link to post
Share on other sites
Quote:
Original post by templewulf
Wouldn't you want to inherit CDirectXRenderer and COpenGLRenderer from IRenderer, in which case all you have to do is fill out functions for your new renderer?


I would. Telastyn's explanation implied that each object does its own rendering which means it has to have specific knowledge about either the API being used or have a pointer to and knowledge of some interface/facade to the API. I was wondering if each Renderable object in his game would have that knowledge.

For my game, a 3D game, I was hoping to be able to factor out all of the common information for each mesh and have that stored in generic containers/arrays. It can then be memcpy'd to API specific containers such as Direct3D vertex buffers and that would be done by and within the Renderer. I am planning to take that approach despite the fact that I have no plans to make an OpenGL version of the renderer.

Part of the case for abstractions is that I am looking at using the Newton physics library. From what I understand from my brief readings, it accepts generic vertex collections and I would need to move the data in and out of that library and then into D3D vertex buffers.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
I'm using D3D currently.

As for the first point, I set a 'context' on entry to rendering [and occasionally thereafter in the rendering process] which wraps the actual pushing bits to buffers. The context is merely a global. It could just as easily be a static renderable member, or singleton. No great overhead there.

Further, it's not that big a deal, because in reality, only two classes that inherit from renderable [that aren't contexts] actually interface with that context currently. Image and Text. Everything builds off of those two building-blocks [and non-D3D renderers like timers]. So to switch to OGL, I would need to re-impliment only those two classes, create new context classes to push bits to OGL buffers, and re-impliment some helper stuff like image loaders.

Since the rest of the renderables deal with images and text though those classes, they can effectively ignore the implimentation, and work without modification.


Are you making a tile based game?

Share this post


Link to post
Share on other sites
Eventually I hope.

The general abstraction should apply to models and animations as well, I've just no ability to make either of those, and little need. And while it might apply, it likely wouldn't be ideal for different sorts of games.

Share this post


Link to post
Share on other sites
I see. It all makes sense now.

I was staying away from Singletons/globals so in my case, it would have meant some overhead to either pass the D3D/RendererWrapper to each object when telling it to Render itself or to have each object maintain a pointer to the D3D/RendererWrapper.

Share this post


Link to post
Share on other sites
Quote:
Original post by RDragon1
Quote:

So the weapon's axe and sword are not seperate classes, but just instances of the Weapon class?


No, they are classes as well. Each game class gets registered into a factory, and that is used to create any object.


Couldn't there be a problem if you were to add over a 100 different items?

So far I have been just been having a couple of classes to represent a larger amount of objects.
eg: different space ship types are represented by one Ship class.
the only differences are usually, mass, mesh, collisionRadius, etc.

Also do you normally have objectType classes.
eg A shipType would have variables like: mass, collisionRadius, mesh?, etc.

and then a ship would have:
position, orientation, linearVelocity and angularVelocity, lpShipType.

Also the shipType, weaponType etc i think would be just another gameobject/entity aswell.

Quote:
Original post by Telastyn
Quote:

So how would that come together with the entities inheriting the rendables?


Since it's just an interface, you can then arrange all of the renderables together, and the graph just calls render() for each. They then can handle the details.


I'm running into problems with this idea though, Of each renderable having a render function.

Because say with a particle system, I would be storing the billboardered vertices into a dynamic vb each frame, so wouldn't the renderable class there just contain vertices of each particles' quad?, and the few draw calls(for each texture) would be done at the end.

But the meshes can be drawn one by one(like your description), although I am also thinking about storing them into a dynamic vb/ib so I can just draw all the meshes in a couple of draw calls. Which I probably will do later, if the game is too slow.

So I need to develop something flexible here that can do the drawing both ways.

Quote:
Original post by blackdot
Quote:
Original post by johnnyBravo
..


The way I was considering doing it was to have one instance of each model in memory. I would be doing quaternion based animations, so the actual animation would be calculated out for each character each frame. I am not stuck to this, so I may go another route. A Renderable would have a pointer to it's model. It would have some animation specific information. ResourceManager loads the instance of each model being used. When the character (Renderable) is loaded, it is given a pointer to the model that represents it.


How about having one renderable for many gameObjectws/entities?
So an entity would have a pointer to a renderable, maybe to get vertices for collision detection.
And the renderable would have an array of pointers to the gameObjects/entities, so it could tell the render class what to draw(eg positions, orientations)?



Also how would you go about connecting a mesh to a renderable to an entity?

Would you treat all things in the game as entities, and then use a factory to create the textures, then the renderables then the spaceships etc?

..............
I'm not getting off course here am I?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this