Search Unity

How bad are singletons on gamedev?

Discussion in 'Getting Started' started by Delshire, May 21, 2018.

  1. Delshire

    Delshire

    Joined:
    May 21, 2018
    Posts:
    5
    Hi! I write this topic since i know this a way of achieving my goal i just dont know if it's the optimal one (or the only one).

    Basically i need to persist data throught the game and get it (or modify it) on different scripts. To put you an example lets say i have a script that creates my character, then to persist all of his information (hp, stats,etc) i make a singleton class called "GameInfo" which has the same properties of my character class and maybe some more info relevant to the game. Then on my Character creation script i could just create my char and save it to GameInfo.Character (being Character an object of the class Character i already made)

    So then if on another script I needed info about my player to do some calculation or to apply some status i can just do GameInfo.Character.Health -= damageRecieved (just to give an example). But not just that since later on i could even serialize all the fields of GameInfo and make a savefile probably.

    My question here is if a singleton is the only way of achieving this since i know singletons are bad practice to programming in general (I dont really know in gamedev) or is there any other way?

    Thanks.
     
    mrshadow2006 likes this.
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Singletons are not bad programming practice. They can be abused like anything else, but it's not like they're goto. And they're much better than the obvious alternative (global or static properties).

    In this case, a singleton is a fine solution if you know that you will never need any other characters with similar data. If you do, then you should make your character data a plain old data class, and maybe just have a singleton reference to the player's data, but still allow for other (non-player) characters to also have their own data.
     
    Delshire and Ryiah like this.
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,534
    Singletons are not bad practice. Improper use of any methodology is bad practice so you just have to ensure that you're using them in the proper place and context.

    Sounds like for your situation they're just fine.
     
    Delshire and Ryiah like this.
  4. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    I don't think singletons are a bad practice. It's a matter of taste. Many people complain about "code smell" with singletons, but I still haven't read any convincing arguments for why they should ALWAYS be bad.

    Apple's APIs use tons of singletons - many OS classes have a shared default version in addition to the option to create a new one or return different types, like the pasteboards (for cut and paste operations) or system preferences. Likewise a game could have a singleton for prefences and/or game saves. But you could also do those via static classes.

    The MonoBehaviour singleton is an OK way to do certain things. You're persisting some data across scenes anyway, and sometimes you need to have a persistent object to hang pooled/preloaded objects you see in every scene off. It could be particle effects, GUIs, sounds which absolutely must be ready to play at any moment, bullets for your current weapons or whatever crazy ideas you think make sense. A singleton makes accessing these lists easier and consistent, and it being a GameObject gives you the option to respond to scene changes inside the singleton itself.

    I think the character example above could be done differently though ;)

    Why not make GameInfo hold everything? If the GameInfo is just an accessor for the player stats, perhaps the Character class isn't necessary at all. It seems like an unnecessary step, and here in Unity-land we like composition, so by golly shall we use it!

    Using getters and setters you could make it handle the damage and health, hiding many different MonoBehaviour classes which affect health, defensive capabilities, status effects and more. Setting strength may set the baseline, but getting it could access any amount of components with bonuses, inventory gear or whatever for a different result.
     
    Delshire and Ryiah like this.
  5. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    814
    I don't think they are always bad (indeed, my favorite alternative to singletons amounts to one singleton that manages instances for the rest of the application) but I do consider them a code smell. In particular, I find that what starts as a couple singletons often turns into an unwieldy bunch of singletons if you aren't actively trying to cut down on the number of singletons in your codebase. It can be way too easy for novice programmers to just turn everything into a singleton willy-nilly.

    I say "unwieldy" because singletons introduce a lot of hidden dependencies, resulting in highly coupled code and making it harder to change one part of your code while being confident that you haven't accidentally broken other things. In the worst cases, singletons are essentially lipstick on a bunch of global variables.

    ---

    As for the OP, I'd go ahead and make a singleton to contain underlying data in the game. However I wouldn't contain the player's data in that class directly, but rather have that singleton class contain a bunch of data containers for characters, global game settings, etc. From your description it sounds like you are already doing that (eg. GameInfo.Character.Health rather than just GameInfo.Health) so mazel tov!
     
    Last edited: May 21, 2018
    Ryiah and Delshire like this.
  6. Delshire

    Delshire

    Joined:
    May 21, 2018
    Posts:
    5
    Thanks for all the replys, they were all really helpful :)