   Global Variables for Game Programming
  I've run into an interesting issue while programming games over the past few years. I'm not a spectacular programmer, but I consider myself competent. My training has hammered into me several concepts, the one that is foremost in my mind is "NEVER use global varaibles".I realize that encapsulation is excellent, and most of my programming uses classes and structures to organize my thinking into objects. My problem arises when I use an external code structure like LUA. I need to give LUA access to specific areas of my engine. It needs individual access, but it is also blind access. I could pass it a global variable that contains all of my "game objects" but I have shied away from this for two reasons. The first is that global variables are bad, the second is that I think another pointer would be a unnecessary (even if small) use of memory. Now, I'm not sure about the speed/memory usage of static member variables and functions, but so far I've been accessing a variable through a static reference (it is a private variable, so I've been using a public accessor function).My question arises as I sit down to begin work on another project that involves lua. What is the best way to expose my engine? So far I'm just going for static references again. This means that I expose a static 'screen' (I am using SDL here) within my game class, and I also expose a 'state' which is the top of my state stack, for object access (entities). The screen isn't really exposed since the game automatically handles all drawing, so I may be removing that feature shortly. I will probably have to expose many more interfaces before this project even so much as moves a block from left to right. I suppose I'm looking for a bit of theory here, specific and general techniques of exposure and scripting access. Thanks!   
  I'm by no means an expert on the embedding of scripting systems in games, but I'll go ahead and mention that I've got a fairly decent component-based entity setup with scripting via Lua, and am not using any global (or static member) variables of any sort.Basically, when a Lua function is invoked, any necessary data or object references are passed in as arguments. Examples might include information about a collision event (references to the objects involved, collision data such as a collision point and normal, etc.), an entity on which to operate, or a 'world interface' providing access to commonly needed services such as sound playback, querying for game entities, and so forth.All of the aforementioned data and objects are member data of some object or another; there's no global or static member data. And, from what you've described at least, I'm not sure why global data would be needed - is there any particular reason you can't just pass in references to member objects?Also, I wouldn't worry about performance- or memory-related issues at this point (especially if you're just talking about an extra pointer here and there).I'll also mention that I'm using Luabind for binding (in case it's relevant).   ;  I can think of a number of things which are usefully "global";The config manager which contains a mix of information off the command line, config files and hardware/software discovery systems.The various factories which manufacture things.Object registries for locating things.The roots of various hierarchical organisations (for example of the user interface objects).{Yes, these can all be implemented as singletons... but that's just prettifying global data}Global variables aren't forbidden -- it's just that their use should be justifiable. The only real reason for having a "never use" them rule is that otherwise people don't migrate data into better forms.;  How do you avoid using them in C?Passing the variables around in the whole program? I use lots of globals (I'm just a fake programmer), so I'm curious about this one.   ;  You could put the variables in structures and pass around pointers to structures....{Which is all C++ does really..};  Yes, that's a good idea, but anyway, I don't understand why is it a bad practice to use globals. (apart from the issues with multithreading, or those are with statics?).If related stuff are structured well into separate source files, and the global variables are used in the scope of that file (so only the functions defined in the file use them), is better (for me) than passing around variables, with which the higher level stuff doesn't have to do anything directly. These variables could be (and should be) hidden from the higher level stuff (which is simple with C++).But I'm not a real programmer, maybe my designs are simply bad.   ;Quote:Original post by szecsHow do you avoid using them in C?Passing the variables around in the whole program? I use lots of globals (I'm just a fake programmer), so I'm curious about this one.In Game Coding Complete he uses alot of psuedo singletons which I'm starting to like:// .hclass A{public:    A(bool setAsGlobal);    static A* GetInstance();};// .cppstatic A *s_A = NULL;A::A(bool setAsGlobal){if(setAsGlobal){s_A = this;}}A::~A(){if(s_A== this){s_A= NULL;}}That way the object is still always owned by something (and get cleaned up correctly), you can have more than one (I have a global lua object (owned by my main game object) while still allowing for individual ones) and you don't have to pass around "global" objects. You have to be careful to only use one but you could do a simple assert for that. Its not perfect but its working out rather well.In answer to the original question, I make sure to put everything I expose in lua to be in a namespace named after my game (so everyhting game related starts GameName.). Things don't have to be global in the c++ code to be global in lua, as long as your shutting everything down in the correct order (closing the lua state before deleting the objects).   ;Quote:Original post by szecsYes, that's a good idea, but anyway, I don't understand why is it a bad practice to use globals. (apart from the issues with multithreading, or those are with statics?).If you give a thousand people a key to your house, and something goes missing, how will you know who stole it?Quote:If related stuff are structured well into separate source files, and the global variables are used in the scope of that file (so only the functions defined in the file use them), is better (for me) than passing around variables, with which the higher level stuff doesn't have to do anything directly. These variables could be (and should be) hidden from the higher level stuff (which is simple with C++).That's more of a module-level variable than a global variable. It's often bad,  because you essentially now have a bunch of singletons, but not as bad as a true global.;Quote:Original post by szecsYes, that's a good idea, but anyway, I don't understand why is it a bad practice to use globals. (apart from the issues with multithreading, or those are with statics?).Globals as such are not bad (excluding static initialization order problems), except for the fact that their scope is vague (per process, somehow managed by compiler).The problems come from use of hard-coded global references. It makes testing difficult, it introduces hidden and implicit dependencies and creates non-trivial life cycles.Instead, as per IoC/DI designs, the following is perfect fine:void foo(Bar & withWhom = DefaultBar::getInstance()) {  withWhom.frobnicate();};Here the default version uses singleton. That's fine - since the code is not coupled to BarSingleton, but merely Bar. It keeps responsibilities separate, foo() does not need to rely on specific allocation behavior or existence and validity of specific global state that developer has no strict control over.And this model transfers directly to concurrency - if multiple threads are needed, just make one Bar in each thread, or have a pool, otherwise just use a global.   ;  I've seen globals and singletons used extensively in the games industry on large projects with large numbers of programmers and i dont recall seeing a single case of "now why has this value changed?". I'm not saying i agree with making things global, but generally speaking programmers don't just go and change things willy nilly.   