• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Shayel

Using global variables - really so bad?

20 posts in this topic

Hi
Ill give you an example.

g_SoundSystem;
class Game
{
  sf::RenderWindow screen;
  State* CurrentState;
public:
  void Start()
  {
     CurrentState->Logic();
  }
};

class Level1
{
  Player player;
public:
  void Logic()
  {
    if(something) g_SoungSystem->Play("shot.wav");
  }
}

CurrentState=new Level1();


I heard that global variables are bad.. but what is the other way to use things like "Soundsystems" etc. g_SoundSystem has to be global so i can use it from any place in the program. I was also thinking about setting flags in certain points but that would also require global access. In other words: Can you help me in understanding how to replace globals?

0

Share this post


Link to post
Share on other sites
I learned in the past one simple answer to your question: it's much more readable!

of course it would be no problem to use global variables for any kind of problems but the simple thing is how bigger your program grow how bigger grow the amount of time you need to repair/add or change something in a proper way!

but if you cannot read your program properly e.g. After 2 years you will run crazy! The same is with singletons, in my eyes the better global variable but unfortunately still the same. In the end it is your decision, perhaps you have some serious reason to use them, then use it. You are free in your decision^^.
0

Share this post


Link to post
Share on other sites

Really having a few globals hanging around is not so bad, especially if they are in their own namespace and there aren't *too many*.

 

So if you have a few "big objects" which you want global instances lying around, then use globals, it's not really a problem.

 

The problem really starts when:

 

* The maintenance programmer can't tell which variables are globals / members / locals etc, easily

* There is so much unstructured global state that it becomes easy to get "stale data" bugs.

1

Share this post


Link to post
Share on other sites
Theoretically, (non-pointer) globals should be faster, because their fixed-addresses are established at compile-time. In contrast, local members or variables that are not declared static will usually be dynamically allocated on the stack or heap, so their memory addresses have to be calculated at run-time, when they are accesse. In the worst case, that calculation is compiled as a simple pointer+offset addition. Practically, the performance of a memory access is usually ruled by other factors than how the address is calculated, and a lot more performance can always be gained with higher-level optimizations than using globals. In fact, locals have an advantage when it comes to being cached by the CPU - since they are always "close" to the other local variables from their parent (stack or object), they have a lower chance of being discarded from the CPU data cache. If your program were to use only global variables, with no dynamic allocation at all, only then you would be able to say that the globals are faster, but nobody does that anymore. :) Plus, initialized globals will increase the size of your executable.
-2

Share this post


Link to post
Share on other sites

Okay, I get why global variables can be bad, but I still don't know how to replace them. In my example it was easy to set correct sound to be played. Now let's say I don;t want to use the global SoundSystem. I could make SoundSystem member of a Game class. But how do I set the correct sounds now, when the "Player" class inside the State, which is already inside the game class, doesn't have access to the SoundSystem. It was easy to check.. if(playerState==state_attacking) g_SoundSystem->PlaySound("swordfling.wav");

 

Another idea was to pass the m_SoundSystem(member of the game class), to the State->Logic, and then to the Player.Logic() but that makes no sense to me. Well, at least I have never seen a source code/example with such a solution.

 

Or maybe I don't need anything like SoundSystem? Maybe simple function playing sounds is enough? However I find SoundSystem much more useful, as it can track which sounds are playing so I don't get the "100000 sounds at a time" effect etc.

 

Any tips from more advanced coders? ;)

0

Share this post


Link to post
Share on other sites

@L. Spiro: I think you are right, but I didn't say that immediate values are faster because they use fewer clock cycles.tongue.png

Edited by tonemgub
0

Share this post


Link to post
Share on other sites

Okay, I get why global variables can be bad, but I still don't know how to replace them. In my example it was easy to set correct sound to be played. Now let's say I don;t want to use the global SoundSystem. I could make SoundSystem member of a Game class. But how do I set the correct sounds now, when the "Player" class inside the State, which is already inside the game class, doesn't have access to the SoundSystem. It was easy to check.. if(playerState==state_attacking) g_SoundSystem->PlaySound("swordfling.wav");

 

Another idea was to pass the m_SoundSystem(member of the game class), to the State->Logic, and then to the Player.Logic() but that makes no sense to me. Well, at least I have never seen a source code/example with such a solution.

 

Or maybe I don't need anything like SoundSystem? Maybe simple function playing sounds is enough? However I find SoundSystem much more useful, as it can track which sounds are playing so I don't get the "100000 sounds at a time" effect etc.

 

Any tips from more advanced coders? ;)

If your only issue is handling multiple sounds at a time, you don't need a global variable keep track of that. It sounds like you're already doing something to have the sounds played in order by waiting for the active sound to finish before starting a new one, or to stop all the active sounds from playing when you want to start playing a new one. You can just do this directly in your Player class.

In the  future, you might want to have some of the sounds playing at once, and some not, depending on the state of the Player. The best place to decide how to play the sounds is inside the classes that represent your game objects. On the other hand, if you code a separate class just for the sounds, you'll have to pass in the objects' states into this class, and then do the same decisions of how to play the sounds a second time inside the PlaySound method.

0

Share this post


Link to post
Share on other sites

Okay, I get why global variables can be bad, but I still don't know how to replace them. In my example it was easy to set correct sound to be played. Now let's say I don;t want to use the global SoundSystem. I could make SoundSystem member of a Game class. But how do I set the correct sounds now, when the "Player" class inside the State, which is already inside the game class, doesn't have access to the SoundSystem. It was easy to check.. if(playerState==state_attacking) g_SoundSystem->PlaySound("swordfling.wav");

 

Another idea was to pass the m_SoundSystem(member of the game class), to the State->Logic, and then to the Player.Logic() but that makes no sense to me. Well, at least I have never seen a source code/example with such a solution.

 

Or maybe I don't need anything like SoundSystem? Maybe simple function playing sounds is enough? However I find SoundSystem much more useful, as it can track which sounds are playing so I don't get the "100000 sounds at a time" effect etc.

 

Any tips from more advanced coders? ;)

What I would recommend is making a base class for your entire game, and adding a SoundEngine object INSIDE the base class. If you ever want to use the sound engine inside an object, you pass it in as a parameter. I would look at the Rastertek tutorials for examples.

Edited by Solid_Spy
1

Share this post


Link to post
Share on other sites

@L. Spiro: I think you are right, but I didn't say that immediate values are faster because they use fewer clock cycles.tongue.png

Outside factors notwithstanding, cycles are what determines speed.

 

As for outside factors such as cache misses etc., globals are more likely to have cache misses than locals (stack data) and equally likely to have misses compared to heap allocations.  The stack is accessed so frequently it is almost always cached, whereas globals and heap data are spread apart and accessed somewhat randomly, or at least less frequently than local areas on the stack.

 

In other words, locals tend to perform the best.  Some devices such as Nintendo DS even reserve their fastest RAM for stack space due to how needed the performance of the stack is.

 

 

L. Spiro

0

Share this post


Link to post
Share on other sites
Inject the sound system in Level1's constructor.
 
public int main()
{
  SoundSystem* soundSystem = new SoundSystem();
  Level1* level1 = new Level1(soundSystem);
}

class Level1
{
private:
  Player player;
  SoundSystem* soundSystem;
public:
  Level1(SoundSystem* soundSystem) : soundSystem(soundSystem)
  {
  }
  void Logic()
  {
     if(something) soundSystem->Play("shot.wav");
  }
};

Edited by Wenzil
1

Share this post


Link to post
Share on other sites

How do you handle your graphics? It may help to think about sound as another rendering system, using audio instead of video as a medium. How does your renderer know what to draw, and where? Do you feed it renderable objects? Does it poll a scene graph? A similar approach shouldn't be difficult to design for your audio system.

0

Share this post


Link to post
Share on other sites

 

@L. Spiro: I think you are right, but I didn't say that immediate values are faster because they use fewer clock cycles.tongue.png

Outside factors notwithstanding, cycles are what determines speed.

 

As for outside factors such as cache misses etc., globals are more likely to have cache misses than locals (stack data) and equally likely to have misses compared to heap allocations.  The stack is accessed so frequently it is almost always cached, whereas globals and heap data are spread apart and accessed somewhat randomly, or at least less frequently than local areas on the stack.

 

In other words, locals tend to perform the best.  Some devices such as Nintendo DS even reserve their fastest RAM for stack space due to how needed the performance of the stack is.

 

 

L. Spiro

 

I thought that was exactly what I said (except for the DS bit), but nevermind... smile.png

Edited by tonemgub
1

Share this post


Link to post
Share on other sites

Not relevant to the topic at hand... huh.png

I might've misunderstood the effective level of privacy that getters and setters can provide. Nvm I guess, just a thought I had after reading Servant's reply. unsure.png

Edited by Malabyte
0

Share this post


Link to post
Share on other sites
It is almost impossible to unit test code that relies on mutable global state, and where it is possible it is usually annoying.

Another issue is that a global makes it very easy to create what would otherwise be considered insane dependencies between distinct subsystems.

Of course, what is the argument for globals, and is it compelling? The most common is it is inconvenient to pass references to these objects everywhere. Of course, this raises two immediate counter arguments. The first is that if the would-be global is really used nearly everywhere, then your project is spaghetti, everything is tightly coupled and there appears to be no modularity. The second if the global isn't used everywhere, then passing to the areas that actually need them probably isn't quite as inconvenient as first thought.

For simple games that beginners make, there are a few approaches that can help. One common issue is that the logic to check for input might end up buried into a Player class, for example. One solution might be to move the logic to check for input away from the player, and to call member functions on the Player class when input is received/

Another is to bundle a few critical systems that really are needed in lots of places (in one game I made, objects to represent the logical and physical game world, the current level, a simple configuration mechanism and the resource caches) together in a context object. This avoids the need to pass several parameters through to the objects that need them. Care needs to be taken with this approach, because if every area of the game has access to the critical objects then nothing has been gained.
2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0