Skip to main content
gamedev.net
🔒 Locked

Global declarations

Started by cherryhouse Mar 24, 2006 at 9:36 PM 1 replies 600+ views
Original Post
cherryhouse
cherryhouse
I was told a while back that declaring global objects/variables,etc was bad programming. That put me in a predicement. I was thinking of different ways to implement weapons into a game, and thought of declaring a global object as an array of 5, then create a function which allows me to simply set the weapon name for each array, giving me 5 weapons with separate names. Would this be considered bad programming or was I just misinformed? an example of what I want to do is: Gameloop.cpp
#include "Library.h"

Weapon object[5];

void SetAttrib()
{
    object[0].SetName("Sword");
    object[1].SetName("Spoon");
    object[2].SetName("Axe");
    object[3].SetName("Knife");
}

void gameloop()
{
    // I would initialize all the items and monsters 
    // the same way
    SetAttrib();
    
    // Done initializing monsters, items, etc
    
    // Gameplay starts
}
Was I told the correct information, but took it the wrong way? Maybe he meant, declaring variables globally in the main.cpp file? I'm not exactly sure, but would this approach be alright or would I be noobish to do it?
Hello?
MaulingMonkey
MaulingMonkey
The problems with globals:
1) They can be modified by anything aware of them. No accountability for determining who changed x to 42 causing your program to crash.
2) They are by nature tied to a single instance of the program. They can't be shared among multiple instances, nor can you have more than one of them in the same program.

Pretending for a moment you were writing a server for this game. If you want to make it so that this server can hold multiple game worlds, each with their own seperate set of weapons (guns for the far future, sharp pointy sticks for caveman times?), you need to replace your global "Weapon object[5];" with something else, breaking every single piece of code that uses those objects.

A solution to both problems is to use classes. Let's take your source snippet and apply some OOP:

class Universe {    Weapon object[5];public:    void SetAttrib()    {        object[0].SetName("Sword");        object[1].SetName("Spoon");        object[2].SetName("Axe");        object[3].SetName("Knife");    }    Universe() //constructor, called when we create a universe    {        SetAttrib();    }        void gameloop()    {               // Gameplay starts    }};


Looks almost exactly the same, dosn't it? But all of a sudden, the problem of multiple Universes isn't a problem:

int main() {    Universe the_far_far_past;    Universe the_far_far_future;    the_far_far_past.gameloop();    the_far_far_future.gameloop();}


Now if we want to change the items used in the different universes, we only have to change what function gets called, so each universe gets it's seperate data:

class Universe {    ... //most of the stuff stays the samepublic:    static const unsigned the_past_timeline_id = 1;    static const unsigned the_future_timeline_id = 2;    void SetPastAttrib() {        ... //objects in the past    }    void SetFutureAttrib() {        ... //objects in the future    }    Universe( unsigned timeline_id )    {        if ( timeline_id == the_past_timeline_id ) {            SetPastAttrib();        } else if ( timeline_id == the_future_timeline_id ) {            SetFutureAttrib();        } else {            //Error!!!            assert( 0 && "timeline_id didn't match a valid timeline" );        }    }};int main() {    Universe the_far_far_past( Universe::the_past_timeline_id );    Universe the_far_far_future( Universe::the_future_timeline_id );    the_far_far_past.gameloop();    the_far_far_future.gameloop();}


So, by correctly wrapping things up from the start (which required just what, 5 extra lines? two of which were single characters?), changes in the future become less expensive. Sure, we might not ever need this particular feature, but unless you're able to see the future, eventually you're going to run into a situation where you have a bunch of code tied to a single global, and for whatever reason, you really really need two of it for seperate tasks.

Globals are "evil". Like all things "evil", they do occasionally have their uses, and in some circumstances you should in fact use them. But do so carefully, with reservation, knowing what you're getting yourself into.
cherryhouse
cherryhouse
So simple, yet I managed to overlook it. Thanks, I thought about this a few times but didn't realize this was the correct way of doing it.
Hello?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.