• 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
Norman Barrows

questions about singletons

40 posts in this topic

questions about singletons:

 

1. the code that makes it so you can only create one singleton is just to prevent you from doing something stupid like creating two entity lists by accident, correct?

 

2. are singletons considered good, bad, indifferent?

 

 

 

 

 

0

Share this post


Link to post
Share on other sites

1. the code that makes it so you can only create one singleton is just to prevent you from doing something stupid like creating two entity lists by accident, correct?

 

Yep along with the Global Access property SiCrane mentioned.  The third property of the Singleton paradigm is control over the relative order of construction of singleton objects, something that's not possible with object instances that are declared as globals.  As with most design paradigms Singletons are mostly used to show intent to would be modifiers of the system rather than to prevent bonehead mistakes by making them syntactically illegal. 

 

As a whole singletons seem to be regarded as a bad pattern due to the global access part. Global state is bad because it complicates multi-threaded code, makes testing and debugging more difficult and frequently makes code maintenance and refactoring a pain. The single instance of  a class part is largely regarded as usually pointless but not harmful in and of itself.

 

Mostly agree in the academic sense but in practice I would say they have their uses stemming primarily from convenience.  Sometimes you truly only want one instancing of something running around (assert tracker, GPU wrapper etc) in which case having a single point of access keeps things simple.  Avoiding the threading pit-falls can be done by proper constructing the singleton to deal with multi-threaded access and being vigilant about keeping singleton access out of code that doesn't absolutely need it.

0

Share this post


Link to post
Share on other sites

Sometimes you truly only want one instancing of something running around (assert tracker, GPU wrapper etc)

 

This is misleading -- You may "want" only one, but it's very, very seldom that one cannot imagine a scenario where, in fact, you actually need more than one, and even more seldom when having more than one would actually be incorrect. Usually when a programmer says "I'll use a singleton because I only want one of these." what he's really saying is "I'll use a singleton because I don't want to bother making my code robust enough to handle more than one of these."

 

If you can justify choosing convenience over correctness you're free to do so, but you've made your bed once you've chosen a Singleton and you alone will have to lay in it.

Edited by Ravyne
2

Share this post


Link to post
Share on other sites

 


 Sometimes you truly only want one instancing of something running around (assert tracker, GPU wrapper etc)

 

This is misleading -- You may "want" only one, but it's very, very seldom that one cannot imagine a scenario where, in fact, you actually need more than one, and even more seldom when having more than one would actually be incorrect. Usually when a programmer says "I'll use a singleton because I only want one of these." what he's really saying is "I'll use a singleton because I don't want to bother making my code robust enough to handle more than one of these."

 

If you can justify choosing convenience over correctness you're free to do so, but you've made your bed once you've chosen a Singleton and you alone will have to lay in it.

 

 

...yeah, 'correctness' in software design; something that's largely considered undefinable.  We are not scientist doing good science or bad science; we are craftsman and what one paradigm holds over the other is simply the kinds of coding decisions that are discouraged vs encouraged.  The idea is to use designs that encourage use cases that pay productivity dividends down the road and discourage use cases that become time sinks.  In this sense Singletons are ALL BAD but making your life easier down the road shouldn't be a directive that is pathologically perused such that the productivity of the moment is drawn to a crawl.  I guess the point I'm trying to make is that a tipping point exists between writing infinitely sustainable code and getting the job done.  Here are some examples:

 

Singletons make sense for something like a GPU; it is a piece of hardware, there is only one of them and it has an internal state.  Of course you can write code such that the GPU appears virtualized and your application can instantiate any number of GPU objects and use them at will.  Indeed I would consider this good practice as it will force the code that relies on the GPU to be written better and should extend nicely to multi GPU platforms.  The flip side is that implementing all this properly comes at a cost in productivity at the moment and that cost needs to be considered over the probability of seeing the benefit.

 

Another example is collecting telemetry or profiling data.  It's nice to have something in place that tells everyone on the team: "Hey, telemetry data and performance measurements should be coalesced through these systems for the purposes of generating comprehensive reports."  A Singleton does this while a class declaration called Profiler and Telemetry does not.  Again, you can put the burden of managing and using instances of Profiler and Telemetry onto the various subsystem of your application and once again this may lead to better code but if the project never lives long enough to see that 'better code' pay productivity gains then what was the point?

 

I don't implement Singletons either personally or professionally (for the reasons outlined by Ravyne and SiCrane unless explicitly directed to do so) but I have worked on projects that did use them and overall I was glad they existed as they made me more productive on the whole.  In these instances the dangers of using other people's singletons in already singleton dependent systems never came to fruition and the time sink I made writing beautiful, self contained, stateless and singleton free code never paid off.  Academic excellence vs. pragmatism:  it's a tradeoff worth considering.  Mostly I'm playing devils advocate here as I find blanket statements about a design paradigm being all good or all bad misleading.  Anyway, this is likely to get flamey...it already is and people aren't even disagreeing yet. :)  I'm out.

1

Share this post


Link to post
Share on other sites

To be honest I just have very rarely(and by rarely I mean once, in C#) found a real use for a singleton and in that case it was more to cover a problem I couldn't get around, I think it related to a certain global having state or something. It had good reasoning at the time whatever it was.

 

Other than that a singleton is really just a global under a really thin blanket. There's no real reason architecture wise that you should need something to only function if it is the only copy of itself. Globals can be useful, sure, but the golden rule with globals usually is that they are objects that won't change, such as constants.

 

Of course even in that case they shouldn't really be bare globals, placing things in namespaces is always a helpful idea, and a global only really becomes a global if you include it anyway, otherwise your unit of code might as well not see that it exists.

 

In general using either a singleton or a global as a point of access for something just doesn't have much of a point, you can accomplish the same thing with dependency passing. I used to feel that it was messy to pass a top interface class like an "engine" or something abstract like that around to allow access to other objects but the fact is that such an object keeps the dependencies bundled together. When you use a full on global object or a singleton you're basically shooting it up into space and letting everyone touch it without you having a clue where they're touching it from or how much code you will break if you modify or remove it.

Edited by Satharis
1

Share this post


Link to post
Share on other sites

We may not be able to imperially measure the goodness of the code we write and systems we design, but we do have a reasonably strong understanding of what's good none-the-less. If we could make perfect statements about what is--now--and will remain--forever--single, then Singleton at least wouldn't introduce that very dangerous assumption. The trouble is: we can't. Not many years ago, the assumption that the GPU was singular in any system might have seemed reasonable. Now, multi-GPU setups are common, things like nVidia Optimus are common (switchable integrated+discrete GPUs), and Hydra (allocating graphics calls among multiple GPUs, even from different vendors) is a thing. Assumptions very often turn out wrong.

 

So now the point may be argued, correctly, that 'forever' is an awful long time to be concerned about. And it is. Probably most software (gaming, anyways) will be developed over a period of 12-36 months, and have an active support cycle of about twice that if the game continues to generate revenue. So, already we are predicting 3-6 years into the future. Now, if we base our next game on the same codebase, we can extend that number out another 12-36 months per iteration. We're now predicting things 4-9 years into the future. Not forever, but in a realm very few people are consistently right at guessing about.

 

So, if we are considering the potential productivity costs of choosing Singleton or not, we have to also consider the unknown cost of guessing wrongly about the uniqueness of the thing, multiplied by the likelihood of our being wrong. On the other hand, if we do not make the simplifying assumption of its singleness, then we do pay a cost now, but we probably have a decent idea of what it is and being more general, rather than less, is not likely to cause us any unexpected grief later on.

0

Share this post


Link to post
Share on other sites


The third property of the Singleton paradigm is control over the relative order of construction of singleton objects, something that's not possible with object instances that are declared as globals.

 

so its supposed to be manually new'ed on the heap by the coder so they control when the constructor runs?  

 

as opposed to some arbitrary order decided upon by the compiler for object instances declared global static?

0

Share this post


Link to post
Share on other sites


As with most design paradigms Singletons are mostly used to show intent to would be modifiers of the system rather than to prevent bonehead mistakes by making them syntactically illegal. 

 

so its more about code clarity and robustness for the coder who comes behind you to make mods later?

 

i was wondering, i mean, if you declare it, you know there's only one. the extra code seemed overkill. at least / especially for a release build of a game where you strip out all unnecessary error and type checking once its stable.    or better yet, don't let it become unstable, and don't put it in in the first place.

0

Share this post


Link to post
Share on other sites


Avoiding the threading pit-falls can be done by proper constructing the singleton to deal with multi-threaded access and being vigilant about keeping singleton access out of code that doesn't absolutely need it.

 

so then you just design it to be "thread safe", with locks, etc, right?

0

Share this post


Link to post
Share on other sites
It's actually harder than it sounds. Look up the double-checked lock idiom in Java for an example of a popular but thoroughly broken attempt at doing thread-safe singletons.
1

Share this post


Link to post
Share on other sites


global state in the form of a singleton is nearly always worse than global state in the form of a common global (though both are very bad to begin with

 

so whats the alternative to a global state?

 

also, what precisely do you mean by global state?

 

a global variable like "int gameover;" ?

 

or a global data structure such as an array of pointers to texture com objects?

 

or both? IE any global?

 

or do you mean something else entirely?

0

Share this post


Link to post
Share on other sites
"State" is a general term for any data which reflects the properties of a changing system. A system has state or is stateful if it can change over time.

Mutable state is state that can take on different values over time. For instance, a global variable that stores player hit points would be an example of global mutable state. So would an array, or a class object, or whatever other linguistic construct you have available to represent values.

Immutable state is state that is always the same value, and does not change. Note that changing systems can still be represented in terms of immutable state, via designs like monads. In fact a good chunk of pure functional programming involves building systems that are described in terms of immutable state.


Generally, when people talk about globals being bad, they're talking about global mutable state, although not always.

The reason global mutable state is bad is that it permits invisible coupling between distant and unrelated parts of code. This should not be confused with "global" variables which are contained to individual modules, such as static file-level variables in C or C++.
0

Share this post


Link to post
Share on other sites


That's not a property of a singleton. That's an implementation detail that some (not all) singletons have that can be extended to non-singleton objects.

 

so they're not necessarily intended to be new'ed, then ?

0

Share this post


Link to post
Share on other sites


Generally, when people talk about globals being bad, they're talking about global mutable state, although not always.

The reason global mutable state is bad is that it permits invisible coupling between distant and unrelated parts of code.

 

so then....     giving say, the renderer "global access" to an array of texture COM object pointers ( static textures - immutable data ) would not automatically be considered bad form?

 

if so, what might be considered a "better way" ?

0

Share this post


Link to post
Share on other sites

so i take it the "better practice" is to just create non-singleton classes, just in case you someday might need "more than one" mesh database, texture database, entity list, player list, projectile list, etc?

 

the difference in effort almost seems trivial. create a class - create one instance.  vs create a class with some special "singleton" code, and create one instance.  right?   am i missing something?

0

Share this post


Link to post
Share on other sites

That's not a property of a singleton. That's an implementation detail that some (not all) singletons have that can be extended to non-singleton objects.

 
so they're not necessarily intended to be new'ed, then ?

Singleton's have a single global point of access. If you could manually create a singleton, say with new, then you wouldn't have a single global point of access.
0

Share this post


Link to post
Share on other sites

Singletons make sense for something like a GPU; it is a piece of hardware, there is only one of them and it has an internal state.

...Except that you don't need global access to the GPU, which is half the design requirement for a singleton.

 

EDIT: I'm sorry. I should note that nonoptimalrobot goes on to describe a a better design immediately after the above quote.

Edited by yckx
0

Share this post


Link to post
Share on other sites


If you could manually create a singleton, say with new, then you wouldn't have a single global point of access.

 

i think in an "example" i saw, they new'ed it, and added code to the constructor so it could only be allocated once. subsequent attempts to create an instance simply returned a pointer to the original instance. 

0

Share this post


Link to post
Share on other sites


Think of all the reasons people hate global variables.

 

i can think of a lot of ways they can be misused, and abused, but i personally find them quite fast and powerful,   and therefore don't really understand why people hate them.    then again, i use them is very specific ways only - ways which i'm hard pressed to find a better solution for.   so, i honestly don't understand the problem with globals.   indulge me for a moment... what's wrong with globals?    in my mind the problem isn't globals themselves, its developers using them in bad ways.  guns don't kill people, people kill people.    globals don't make bugs, developers make bugs.    so help me out here. i honestly can't think of a reason to hate globals, unless i have to work with a numbno coder who can't use them correctly.  part of all my questions about game architecture and c++ recently is grounded in the fact that i tend to use global / singleton data structures for the combo of ease and performance. and giving up those globals so far is looking like more work to run slower.  i mean am i supposed to use a setter and getter for everything? technically, everything should have a gettter and setter and no member data variables should be public. technically its a global. sure maybe only to the current source file, but believe it or not, instead of the usual 20-30 files, i've got all 70,000 lines of CAVEMAN in one cpp file this time. its all nice and neat and laid out like 30 separate modules, just all in the same file back to back.

1

Share this post


Link to post
Share on other sites

You always seemed like a really knowledgeable guy using tried old methods which work well for you, but your latest threads feel like you now want to follow the OOP+patterns crowd cause everyone uses them? I doubt it would help you much, considering some people are already partially getting away from these again and for example using data oriented designs or entity-component-systems.

There's some links about peoples views of design patters I unintentionally found some time ago:

http://perl.plover.com/yak/design/

http://realtimecollisiondetection.net/blog/?p=81

0

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