Why a "Game" class?

Started by
11 comments, last by Icebone1000 10 years ago
Hi,

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)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement
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.

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.

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.

greetings

S T O P C R I M E !

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

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.

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').

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

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.

greetings

S T O P C R I M E !

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

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


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.

throw table_exception("(? ???)? ? ???");

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.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement