More efficient game structures?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Alon
Posts: 7
Joined: Fri May 16, 2014 9:42 pm

More efficient game structures?

Post by Alon »

OK, I've been trying to find out how I should do this for a long time, but I still don't quite understand it.

Let's say my game has a certain structure. From my main function, I initialize a "Game Manager" class, and that class initializes a list of "Game Object" classes, all included in the Game Manager header file, which is included in the main.cpp file.
Each gameobject needs the ability to do things like play sounds, interact with the IrrlichtDevice, physics engine, etc... all in its update loop or whatever. Now, what I've been doing is passing pointers (To the irrlicht device, the sound manager, etc.) to each one when it's created by the Game Manager, and that's it. But what I'd like to do is find some way for it to interact with the Game Manager directly without running into a problem with circular inclusion. Or some way to have certain functions and variables be totally universal without running into that problem. I was looking into the modular approach the Source Engine takes, but I don't really understand how it works at all. It seems way above my current skill level, and I can't find anything to break it down so I can understand how it works.

I'm also wondering, is it a better idea to derive my game classes from Irrlicht scene nodes, or to have the classes be something updated each frame by the Game Manager (Which also runs device->run()) and have Irrlicht scene nodes created/owned by the game classes?

What does everyone else suggest? How do you structure your games?
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: More efficient game structures?

Post by Asimov »

Hi Alon,

I am new to irrlicht, but in the past I have done it this way.
I use the main entry point as my manager in main.cpp.
Then nothing is really run in main but it is where all my classes are loaded.

If I have sound. I make a sound class. Then I will have a class to load my sprites, Then I might have a class which does nothing but add up the score, or something equally boring.
I have used this method for various games.

Now I am using irrlicht and I am tending to do it the same way, but still on the steep learning curve. For instance I have made a loadmanager class. This handles loading of all models. Then I have made a hotelsandhouses class. This is intended to keep track of all my houses and hotels in the game, but also that class uses my loadmanager to load my houses and hotels. I have also put the event handler in another class.

Basically I like to keep my main.cpp as clean as possible, but as a place to call my other classes, and of course hold the game loop.

Not sure if it is the best way, but it works for me.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: More efficient game structures?

Post by REDDemon »

just make it easy to code so separate into classes where you think a class is needed (a class is just operations that operates on a common set of data, if you are still not confident with coding do not try to overthink thnigs like interfaces and inheritance).

Decide upfront what game you want and remove useless features untill you get something you can code in 1/2 days to get something displayed on the screen.
Then try a different game (don't attemp to finish them, just make them interactive a bit so you can start experiencing in coding)
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: More efficient game structures?

Post by CuteAlien »

If everything works out this time I'll open-source my game in 1-2 weeks. Until then - browse games-sources in sourceforge maybe.

Not sure what you mean with circular inclusion. Maybe the thing your are missing are forward declarations? You use those so you can use pointers without having to include a header in a header.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Alon
Posts: 7
Joined: Fri May 16, 2014 9:42 pm

Re: More efficient game structures?

Post by Alon »

Forward declaration usually results in more problems the few times I've tried it. Guess I'm just doing it wrong.

The way I'm doing it seems to work. Having a few extra pointers never hurt anyone, right?
Is there any way I can, say, make a global pointer that's assigned a value at runtime and then used by all of my classes?
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: More efficient game structures?

Post by Seven »

it isnt good programming practice, but i use a global pointer like this...........
a static instance that is always available, but everything refers to the address of it.
allows me to change the global logger at runtime but always have a default logger to refer to ...

Code: Select all

 
// unclutter the global namespace
namespace CS
{
 
    CSLogger logger;                    //  global logger variable
    CSLogger* globalLogger = 0;         // pointer to current active logger
 
    // set up the pointer to the logger variable
    void setGlobalLogger(CSLogger* l)   
    { 
        // if the logger is valid, copy all of the current logger strings to it
        if (l)
        {
            list<LogText>::Iterator it;
            for (it = getGlobalLogger()->m_TextStrings.begin(); it != getGlobalLogger()->m_TextStrings.end(); )
            {
                l->print( (*it).m_Type, (*it).m_Text);
                it++;
            }
        }
 
        // remember the pointer
        globalLogger = l; 
    }
 
    // get pointer to a valid logger, if it doesnt exist then get pointer to global logger
    CSLogger* getGlobalLogger() { if (!globalLogger) globalLogger = &logger; return globalLogger; }
}
 
Alon
Posts: 7
Joined: Fri May 16, 2014 9:42 pm

Re: More efficient game structures?

Post by Alon »

Ah.... so that's a method of doing that. Thanks. ^_^
And why is it "bad practice", exactly? Like, what problems can it cause?
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: More efficient game structures?

Post by CuteAlien »

Same problem as any global variable - it makes it hard to read your code in a few months (or by anyone else). The trouble with globals is that every part of your code can affect them. So usually you try to reduce the amount of a variables any class can access as much as possible. Then looking at a class you know very quickly which parts of your application it can change. While when a class starts working with global variables then it can suddenly do all kind of things - and the only chance for you to figure it out is reading through the whole sources of a class (instead of seeing that stuff with a quick view at the header). This works somewhat as long as your application is small, but once your applications grow you start losing the overview then. So instead try and pass pointers to exactly those object which class needs to have - no others.

And forward declarations are often necessary. Think of the following case:

Code: Select all

 
class A
{
   B * b;
};
class B
{
  A * a;
};
 
This is impossible to solve without forward declarations (in this case for B). And that's something you need all the time.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: More efficient game structures?

Post by Asimov »

Hi Alon,
Ah.... so that's a method of doing that. Thanks. ^_^
And why is it "bad practice", exactly? Like, what problems can it cause?
It is very bad practice and a nightmare to debug.

It is best to stay away from global variables. If you need to pass a variable to a function, it is easy enough to do. There is very little need for global variables, if you structure your game well.

Say I have a variable called test in one function and I make it global. Then if you use the same variable in another function it can become corrupted,or changed. Then you have the hard job of looking all over your program for the bug. It is best to keep variables within their class, if you need to access it from outside that class, then the other class can access the variable outside without having to use a global variable. You can either make a variable public, so that it can be accessed outside the class, or you can have a function to return the variable.

I don't see anywhere in a program where a global variable is necessary.
Alon
Posts: 7
Joined: Fri May 16, 2014 9:42 pm

Re: More efficient game structures?

Post by Alon »

So, it's more efficient to just pass around pointers to the same thing to all of my classes that need to interact with it, then?
Guess that means I've been doing it right all along then.

See, it's just that each class ends up having either a really bloated constructor taking arguments for pointers to my irrlichtdevice, sound engine, physics world, etc.... or ending up with a lot of functions to set up the pointers individually that I call before they're needed. Feels kinda cluttered to me. Would be a lot easier if, say, my player class could call the GameManager it's a child of to get its IrrlichtDevice as needed, or to call GameManager function X, Y, or Z... can I set something like this up with forward declaration, and have my Player class have a pointer to its parent?
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: More efficient game structures?

Post by Seven »

all of this is true, however, in the end, my code works for me, and that is what you will need to decide. What works for you? There are always great intellectual debates regarding global variables, singletons, and the like, and all of them are valid from a specific point of view. Since my logger class was needed by literally all other classes, it was easier for me to just make it global and not worry about it.

However, with all of that said, it really is a terrible programming practice :)
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: More efficient game structures?

Post by Seven »

oh, i forgot to add.......

I was simply answering your question "Is there any way I can, say, make a global pointer that's assigned a value at runtime and then used by all of my classes?" and not making recommendations........
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: More efficient game structures?

Post by Asimov »

Hi Seven,

What would this pointer used for, and is there a reason all your classes need to see it?
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: More efficient game structures?

Post by CuteAlien »

@Alon: Doesn't really make a difference for efficiency. Don't think to much about that anyway - unless you have *lot's* of game-object the structures you use and the amount of pointer passing and similar stuff won't even matter. Once you talk about 100.000's of objects that stuff starts to matter, but then it's mostly about coding in a way that is cache-friendly. But that's really hi-end stuff and you shouldn't even care about that usually. Instead start by coding readable code first. This is far more important (and will always be - even game-companies code foremost for readability).

Bloated constructors are often a sign that your class itself is getting too fat and should be split.

And about logger - yeah - it's one global variable I also have in all my apps :-) It just makes sense for that case. Same for debug-output classes and profilers. It's just additional output which shouldn't conflict with the game logic/states, so I see no loss in readability using globals for those.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: More efficient game structures?

Post by Seven »

In this case it is a simple logging class with only one virtual function. Print(strings text). Since everything needs to log, making it global saves me from passing it around. In addition it allows me to begin logging upon program start and not only after creation. Last but not least, the logger changes hands throughout the life of the program so it is nice that it can do so. For example, using MFC for part of the program and allowing the user to use multiple controls for the logging event and reverting to the windows console when not in use.
I am certain that it can be passes around, it's just that for me, in this application, it is easier this way
Post Reply