Jump to content

  • Log In with Google      Sign In   
  • Create Account


We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.

Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!

Why a "Game" class?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
12 replies to this topic

#1 cozzie   Members   -  Reputation: 1770


Posted 06 April 2014 - 04:38 AM


Everytime I see some game's source code (just a sneak peek), I see al class "Game" (or CGame).
Was just wondering, in my own main application I declare objects for input, io, audio, 3d scene etc. Global in the cpp file.

Would the game class be having all of these as a member, so you need only one "game" objects? (and also put your other stuff in there what otherwise would be global in your cpp main file)


#2 rip-off   Moderators   -  Reputation: 8762


Posted 06 April 2014 - 05:55 AM

There is no objectively "right" way to do this.

Many people, myself included, dislike globals. A common solution is to take objects that live for the entire duration of the application and move them to such a Game class. An advantage here is that you can then pass this class to helper functions, which might reduce the length and complexity of your main function. A disadvantage is that if this object is passed too far, then it becomes effectively global and some of the benefits of not having actual globals are lost.

I wouldn't worry too much about copying this pattern. A more pressing issue is ensuring that, as your game grows, the code remains manageable and understandable, and having minimal coupling between unrelated sub-systems becomes important. High coupling is possible with and without globals, but the ease of access to a global certainly increases some of the risks.

#3 NathanRunge   Members   -  Reputation: 538


Posted 06 April 2014 - 08:24 AM

Using a game class has a number of other potential advantages. Firstly, it can allow you to benefit from inheritance and polymorphism. If you're utilising an underlying framework, that framework might provide a Game class which can be extended, thereby handling much of the lower-level stuff. Certainly this can be handled using a number of separate systems, but there's certainly scope for conveniently handling timing values and calls to update the input system through a base class.


In the same way, you can benefit from polymorphism. In the Heron Framework, which I've developed and used for a number of years, there are multiple extensions to the game class that provide more specific functionality and, more importantly, there are different versions for different platforms. Once again, there are other ways to approach these issues but this is one convenient one.


There's also the possibility to consider scope for multiple 'games.' In Heron, there's a 'GameMode' class which provides the functionality of a game loop but is managed by a game. This effectively allows multiple 'Game'-type classes to be created, loaded, unloaded and run. In this manner separate components can be loaded separately and unloaded when not required, though this is usually handled in other ways. More often, I use this class to create a single game class in a portable library.


A final way in which multiple 'Games' might be employed are in tools. While not games, a number of the tools I have created employ Game classes to manage components that utilise the graphic device and may also employ the input system or content pipeline. In such cases it is beneficial to separate the game from the remainder of the application, and also sometimes necessary to create multiple games and run them simultaneously.


These are some of the reasons I, personally, choose to use game classes. Like rip-off, I also have an aversion to globals. That said, there are many other valid approaches to the problem, such as utilising a graph of systems and components. 

Personal Page: http://www.nathanrunge.com/     Company Page: http://www.ozymandias.com.au/

#4 the incredible smoker   Members   -  Reputation: 407


Posted 08 April 2014 - 09:53 AM

I love globals, so you only have to declare them once, also not passing in functions, just use external in the header file.

Next to game class i also have demomovie class, mainmenu, briefing, options, credits, etc etc.


S T O P   C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70  Working on : LevelContainer class & LevelEditor

#5 frob   Moderators   -  Reputation: 22779


Posted 08 April 2014 - 01:55 PM

Global variables (in newer languages, sometimes called static values in static classes) have been studied in software engineering for about six decades.

While they certainly do offer some immediate convenience, they generally are bad for design and maintenance. They introduce hidden dependencies between systems. They are extremely easy to corrupt. They do not play well in multithreaded or multiprocessing environments. Their lifetimes can be difficult to manage. And on and on. Google can find long lists and technical papers describing the problems they pose.

However, they are a part of most languages. If you are very careful in the rules of modification and access, with rules about who and when and why, it is possible to minimize the problems they cause.

As for having a "Game" class, you are right that it is very common to have some sort of broad container for the game. Call it the simulator, or the world, or the game, or whatever you want.

There are quite a few benefits to having it independent. The ability to throw it away and start over clean is pretty clear when a game has a "new game" or "load game" option. Also if you have some sort of 'attract' screen, such as an AI simulation in the background during the menus, this can be convenient. If you have automated tests they are useful, either through unit testing or acceptance testing or simply letting AI battle AI in a constantly-running server process to help with stress testing, the ability to create multiple independent instances is useful.

In some games I've worked on, we had a farm of computers that ran AI versions of the game continuously, sometimes with hundreds of instances of simulations running in a single executable. They run headless (meaning no graphics or sound attached) so a single server can run many instances concurrently. When one crashes, the graphics get attached and an email is produced, allowing programmers to look at it and find the bug. This is an incredible resource for constant stress-testing of the game and engine, but it would not be available with a bunch of global objects, shared states, or icky singletons.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.

#6 cozzie   Members   -  Reputation: 1770


Posted 08 April 2014 - 02:25 PM

Thanks for all replies.

I'm gonna make a game class for sure, but first I'll probably have to make a basic design on the 'whole game'. So my decisions on which classes should be part of the 'game class' are logical. For example my audio and input class will not change during runtime, so they wouldn't need to be reloaded (as part of a 'new game').

#7 the incredible smoker   Members   -  Reputation: 407


Posted 09 April 2014 - 08:42 AM

Hello Frob,

I got voted down for these reasons about globals ?, i feel special now that i can handle it then.

Once the engine works like this, there is no more of these problems.


Anyways are using globals also slower ?


The point for me is that i have all data / pointers in 1 file ( ok 2 files ( cpp & h ) )

i like to make many games, so i dont have to hunt everything down when cleaning the engine.

Its realy comfortable, professors can discuss another decade about it, but it wont convince me.



Edited by the incredible smoker, 09 April 2014 - 08:47 AM.

S T O P   C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70  Working on : LevelContainer class & LevelEditor

#8 L. Spiro   Crossbones+   -  Reputation: 14314


Posted 09 April 2014 - 09:35 AM

Once the engine works like this, there is no more of these problems.

You do not have the skill level necessary to evaluate that.
For example, you have hidden dependencies (as you admit later), but you seem to think you don’t.

The point for me is that i have all data / pointers in 1 file

That is disgusting.

so i dont have to hunt everything down

If you can’t remember where things are in your engine you lack a very basic skill.

when cleaning the engine.

Except you have a bunch of globals over a small amount of files; by definition it isn’t “clean”, it is disgusting.

professors can discuss another decade about it, but it wont convince me.

Being stubborn and unwilling to learn/grow/adapt is not a characteristic worthy of bragging.
You’ve basically just said, “I learned the wrong way and I am stuck in it because it is my wrong way.”

I don’t personally care because you have basically implied that you will luckily never be working on real production code. It’s your career you are flushing, but for the rest of us it’s probably better that you do so. Imaging one of us having to maintain your code in the future. What a nightmare.

As for the game class, there is no reason to make it global, but the scope of it as viewed by myself is different from that of frob’s.
Although it is instance-based and there can be as many as you like in theory, actually a game class does not represent something you would destroy and recreate on a “New Game” screen. The game is running even if you are on the New Game screen, the title screen, credits, etc.
If you want multiple games running at a time it is possible, but the duration of a game class is from the “power on” to “power off” on a console.

Each screen, such as the menu screens, credits, gameplay area, bonus rounds, etc., are just states within the game.
You can limit yourself to one game state active at a time in a game and allow many games to run at the same time, or make one game instance and allow many states to run at the time time, but ultimately you can do all the same unit-testing as described by frob, letting AI’s go at each other repeatedly for days on end in multiple instances simultaneously etc.

As shown in my articles the game class does not need to be global because it is passed to states and already easy to access at any time.
From it you can get general information about the game plus per-game custom information programmers add when they inherit from CGame. As you would expect, this includes high scores, game settings, etc.

L. Spiro

Edited by L. Spiro, 11 April 2014 - 09:16 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#9 Ravyne   GDNet+   -  Reputation: 8191


Posted 09 April 2014 - 03:03 PM

I got voted down for these reasons about globals ?, i feel special now that i can handle it then.


You got voted down because you're sharing an obviously inexperienced stance as a viable alternative to the advice that near-countless professionals, authors, professors, and Nobel, ACM, et al prize-winners have studied and used over decades. Its a bit like telling people that they can ride their bicycle down the striped line in the middle of the road safely because, after all, there seems to be enough space and you've been doing it for a few blocks, twice a day, for like 3 months now, and it hasn't caused you any harm yet.


And to reiterate what's already been said. espousing your own steadfast ignorance of the matter as a virtue is a bit beyond the pale.


Once the engine works like this, there is no more of these problems.

Setting aside even the *tomes" of academic work and professional experience on the matter of software engineering, you're making a critical mistake that software is ever 'done' -- sure, there comes a time when you're done with it, but the software itself is never complete in any true sense. Even before you're done with it, you have to maintain it, extend it, refactor it, track down its bugs and squash them... Globals make all of these things harder, having everything in one place and file makes all of these things harder.


You can only maintain a position like yours if you are completely ignorant of these practices. If you've never written a program more than a couple thousand lines or so, then you may simply never experience the scale of problem that would surely shake you from your slumber. If you have written a program larger than that, and without changing your tune, then you are being willfully ignorant.

#10 cozzie   Members   -  Reputation: 1770


Posted 09 April 2014 - 04:21 PM

Interesting reactions and input, thanks.
I'll go draw out my high over design and decide where to do what with the game class/ globals.

#11 the incredible smoker   Members   -  Reputation: 407


Posted 11 April 2014 - 05:54 AM

Hello, I just looked in my engine, I forgot i have a DataLoader class now.


So i just do like this :


DataLoader load;


load.SetFolder( "foldername" );

load.Texture( true , "name" ); // true is for global or false = each level


The DataLoader remembers the name, so it wont load twice.


Now with this i only have one global , and that is DataLoader load;

I,m hoping to get voted up now for once!


@Ravyne : Saying that i am uneducated, but not giving a better solution ?

S T O P   C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70  Working on : LevelContainer class & LevelEditor

#12 Ravyne   GDNet+   -  Reputation: 8191


Posted 12 April 2014 - 01:02 PM

Now with this i only have one global , and that is DataLoader load;

I,m hoping to get voted up now for once!

You don't typically get voted up for making your own problems better. Or even voted down for making yourself problems.

You get voted down for encouraging others to adopt your mistakes.

It should come as no surprise then, that helping others to avoid the mistakes you've made or that you know are mistakes is the way to get voted up.

@Ravyne : Saying that i am uneducated, but not giving a better solution ?

Better solutions are well known. Abuse of global is the first thing covered in any software engineering course or book. Even most introductory programming classes or books will get around to mentioning in their first half.

But somehow you missed this information, and instead glibly recommended against best practices and then boasted how good you must be to not have experienced any of its known problems.

I'm probably coming of harshly, but I'm just being frank. Everyone is welcome here but don't expect to be awarded points for mere participation. When you offer up advice, that advice will be judged. So before you offer it, consider whether it is good advice and whether you are actually qualified to judge whether it us or not. If you want to share something that there's no consensus on, present it as opinion rather than fact. And if you want to share something that is contrary to best practices, qualify when the problems can be ignored.

For example, if you had said something like "In small, throw-away projects under a couple thousand lines long, I like to just use global when I'm coding from the hip." is an entirely different answer than "I think globals are great!" and it probably wouldn't have gotten any down-votes at all.

#13 Icebone1000   Members   -  Reputation: 1152


Posted 13 April 2014 - 12:29 PM

In my engine the Game class holds the state machine, hig perf timer, and the fixed step loop, feeded by the timer down the state machine.

When doing a game, I create a GameName class, derived from both Game and Window (Window is a wrapper for win32 windows).

In that class I put the other engine main systems, like sprite renderer, sound, networking. And overwrite the wndprocedure function from the Window class, for handling resizing /input etc. ( I initialize the systems on WM_CRATE).


My message loop is handled manually, I dont know how to make it part of the engine. I place the Game::FixedStepLoop() myself on the main, and just need to load the first state to start the game. Till now all states I create grab a pointer to the GameName class on initialization, to access the main systems.

Edited by Icebone1000, 13 April 2014 - 12:30 PM.

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.