Singletons

(Edit. Just in case certain people don’t know, this is in Slick2d’s library)

There doesn’t seem to be an easy way to transfer data through states without singleton.

I tried using singleton, but the class failed to ‘save’ the data when made in other states. I need to do this so I can transfer the players stats through parts of the game.

Maybe I made singleton the wrong way?
Here’s my Singleton:

package edu.bgp.global.utilities;

public class PlayerStats {
	private static PlayerStats stats = null;
	
	public String playerFirstName = "";
	public String playerLastName = "";
	public int playerAge = 0;
	public int playerZodiac = -1;
	
	//------First int
	//0 is Bravery (Attack)
	//1 is Willpower (Defense)
	//2 is Agility (Evasion)
	//3 is Intelligence (Magic)
	//4 is Comprehension (Modifies EXP gained)
	
	//-------Second int
	//0 is the level
	//1 is the EXP
	//2 is the EXP next
	
	public int playerStats[][] = new int[5][3];
	
	public int day = 1;
	public int month = 1;
	public int birthday = 1;
	public int birthmonth = 1;
	public String timeOfDay = "Morning";
	
	private PlayerStats(){
		for (int a = 0; a < 5; a++){
			playerStats[a][0] = 1;
			playerStats[a][1] = 0;
			playerStats[a][2] = 100;
		}
		
	}
	
	public static PlayerStats getStats(){
		if (stats == null){
			stats = new PlayerStats();
		}
		return stats;
	}
}

Address the real problem at hand, don’t try and blindly bolt singletons on to it.

Perhaps you could explain your original issue and what about it that didn’t work?

Paraphrased: “Some people, when confronted with a problem, think ‘I know, I’ll use singletons.’ Now they have two problems.”

aaaahhhhhhh, kill it with fire!!!

no seriousesly, that is really bad, tells a bit more about what specific things you try to do

The problem is quite clear, if you could understand the simplicity of the question; however, obviously, you cannot.

What’s wrong with the singleton? Their purpose, as I have read, is to make a “global” data keep as sorts. This one isn’t.

Paraphrased, “I’m an idiot, so I make myself feel better by making other people look like idiots.”

To be more specific, I essentially call the getStats after modifying it in another State. It returns the initialized values.

Sorry If I seem angry, but if you’re helping someone, you don’t make them feel stupid. I’d rather you not even answer the question, I’d rather wait for someone like the ra4king guy to come by. He’s an example of actual constructive assistance.

Edit.
I fixed it. Sorry I flipped.

Folks are just trying to say that singletons are usually frowned upon, for several reasons.

One alternative to using a singleton for game state would be to pass the needed game state class instances into the states, either by a constructor or a setter method.

Also, if I may make a suggestion, it’s probably a better idea to use getters and setters to access an individual player’s stats, rather than using a 2D array (not sure why 2D?) public field in PlayerStats. In your current implementation, States have to essentially know “magic numbers” to know how to access data == bad. By following standard Java conventions and creating a class with getters/setters for individual fields, while more verbose, will be much easier to maintain, and keep callers from having to know implementation details like what array index represents what (or whether the data is stored in an array at all, which in this case I’m not sure it should be). For example:


int someValue = PlayerStats.getStats().playerStats[1][1];

vs.


int someValue = playerStats.getExperience();

Thanks for the advice, I’ll use it!

Edit! Oh and to clarify, it’s a 2D for certain stat modifying loops in the game.

Just chiming in with the chorus here: singletons are almost always a bad idea.

Why would you hard-code yourself to a single instance of a global variable and introduce tight coupling when you don’t need to?

What I have done is that I have an instance of my game state instantiated and assigned to a member variable pretty high up in my inheritance hierarchy. Most if not all of the derived classes have access to that parent class and thus have access to the game state instance.

In my own experience I’ve found that not limiting myself to a singleton has come in handy. For example, my new game and load game routines return a new instance of the game state which I then re-assign to that member variable. Easy to conceptualize and understand.

As for some history, singletons were included in a Design Patterns book that many aspiring programmers used as gospel without understanding that some patterns aren’t necessarily always a good thing. http://accu.org/index.php/journals/337

But to answer your original question I need a better description of what you’re trying to do as I don’t know the ins and outs of the Slick library.

You posted a very vague problem and a half-hearted solution involving a design pattern that was completely unnecessary. We can’t help you if you don’t provide enough information in the first place.

If you really want an answer to your question of ‘how to get data from one state to another’ then it’s ‘pass the data as an argument into a method or constructor call’. But if you can give us a more concrete example of what you’re having problems with then we can give you a more helpful response.

(the ‘now you have two problems’ thing is a reference to a joke about the same thing with regular expressions, I guess you haven’t heard it otherwise you wouldn’t be so touchy).

Also, you might want to read this: http://catb.org/esr/faqs/smart-questions.html

I am pleased to inform you that singletons work just great for me :slight_smile: Having plastered them everywhere I then got on with finishing some games.

In theory the software engineers have it right. In practice, I win :slight_smile:

Listen to this: http://the-witness.net/news/2011/06/how-to-program-independent-games/

Cas :slight_smile:

I don’t know any “official” arguments against singletons, but just answer this:
What is the difference between a bunch of static variable and a single static instance with a bunch of variables?

It has the same problem as static variables.

Would that the the problem where you finish the game and make some money? I love statics too.

Cas :slight_smile:

To give Sky some constructive help, I wrote something up,
a bit to long for the forum so here u go http://pastebin.com/9pumEgeg

Despite what over people might say about OO desgin, I think that it makes thinking about problems a lot easier.
Just split up everything in little logical blocks, like u would in real life.
i.e. you have a character who has some stats, other “things” in your world will probably too.

So jsut create some stats class first, and then go on with this. Always remember that every part should only know just enough of other things to function.

It isn’t that singletons, or globals, are automatically bad. It is that lots of them often lead to problems with re-factoring and maintaining code. Namely:

  • Singletons presume there will only ever be once instance; the moment you need a second (including wrapping or replacing the first) you run into issues
  • Where are they used? Where is it setup? Passed objects around leaves a paper trail, which is much easier to follow.
  • Some singletons require being initialized/setup before use, and so you can often you call into code which presumes you have done this, and then errors mysteriously when it’s not been done. It’s much worse if this is done in multiple places, or if you have two sections of code that both want setup the singleton in different ways.

I have used singletons for handling sound in games, for hiding OpenGL contexts behind a ‘more OO’ interface, and for when I’ve wanted to pass a single reference into a constructor without exposing it in the interface (I do this in an MVC framework I built where all Controllers have a reference to the core Framework instance). In all cases, they worked perfectly, and I’ve had no issues.

I have also been given code that has required anywhere from 1 to 40 global variables being initialized, before calling into various different pieces of code, without that information ever being documented (different variables also needed for different code paths). Although that is with globals, you can build a similar mess with Singletons.

For player stats, it’ll work fine, if there is only ever one player. The moment you want more players, such as multiplayer or by faking them as computer opponents, you can start to run into issues. If you do keep the singleton, I’d at least try to touch it as little as possible, so it’s easier to rip out if you ever change your mind.

there are two types of code

#1 code that solves your problems, and that only you or maybe some very few people you know will have to use
in this case, focused on problem solving and on a product, you can get away with almost anything and especially statics/singletons
The arbitrariness your code has to handle is limited to your game.

#2 code that is reusable by anyone.
in this case you are expected to use the best style, documentation - basically everything good and nothing bad
this software is designed to be used by others for anything - therefore it has to be structured as good as possible

as #2 is the standard case when developing software, this is the default answer

however cas is making games, as most people here should
in that case, especially when not many people work with your code, its much faster and easier to do what you feel makes sense

one of the problem with statics/singletons is testability. methods, routines, algorithms - they have to be deterministic, however statics can change behind the scenes
if you wanna know more, watch this google talk: http://www.youtube.com/watch?v=-FRm3VPhseI

its like building a device in your home to solve one problem - against designing parts and plans in the industry.

Sending anyone to ESR’s heavy-handed pompous lecturing tome is certainly the way to get rid of someone. Here’s my entire replacement for the whole meandering farrago:

  1. Be specific
  2. Be considerate

I disagree, it’s much complex then that, because using code and maintaining code are not the same. You can’t really place them into the same bucket.

Externally, code should aim to have clean APIs, with no quirks and gotchas. However internally, code often needs to use anti-Software Engineering methods to gain performance, and to implement/fix corner cases with public API usage.

In my experience there are very few good solutions. It is often a case of picking the best bad solution, and boxing it’s negative aspects into a corner so they are better isolated from the good code.

oh boy, if I would ever listen to all the clean code bloat my current game would not be near demo status. Not even close :smiley:

If you pick the good bits, and use them wisely, then it can often end up saving you time.

I’m sorry but I had to smile on the “…end up saving you time” :slight_smile: No offense I can understand the arguement but I am not doing any scalable software for a large company. I’m doing a game. The only thing which saves time is doing something which can be seen on screen as soon as possible. I once heard this is called fast-prototyping, but I’m no Software guru^^ I can’t just sit around and think : “huuuh… how to I implement this using all the freaky patterns I learned, I mean I did not learn them for nothing so why not using them to make a system which might save time in the future!”.
So I say yes you a right IF and only IF I am working on something elsse then a game (Not sure about AAA-Games, I guess there is some agreement about code sytle but not on “WE MUST DO THIS THIS WAY”.)

[quote]The only thing which saves time is doing something which can be seen on screen as soon as possible.
[/quote]
That is. Right.