Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Singletons  (Read 5193 times)
0 Members and 1 Guest are viewing this topic.
Offline SkyAphid
« Posted 2012-01-23 00:06:34 »

(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:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
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;
   }
}

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #1 - Posted 2012-01-23 00:46:50 »

There doesn't seem to be an easy way to transfer data through states without singleton.
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."

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Danny02
« Reply #2 - Posted 2012-01-23 01:20:38 »

aaaahhhhhhh, kill it with fire!!!

no seriousesly, that is really bad, tells a bit more about what specific things you try to do
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline SkyAphid
« Reply #3 - Posted 2012-01-23 01:22:41 »

There doesn't seem to be an easy way to transfer data through states without singleton.
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."

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.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline BoBear2681

JGO Coder


Medals: 19



« Reply #4 - Posted 2012-01-23 02:18:13 »

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:

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


vs.

1  
int someValue = playerStats.getExperience();

Offline SkyAphid
« Reply #5 - Posted 2012-01-23 02:37:26 »

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:

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


vs.

1  
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.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline loom_weaver

JGO Coder


Medals: 17



« Reply #6 - Posted 2012-01-23 06:15:21 »

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.
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #7 - Posted 2012-01-23 08:37:57 »

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.

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

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #8 - Posted 2012-01-23 08:55:04 »

Why would you hard-code yourself to a single instance of a global variable and introduce tight coupling when you don't need to?
I am pleased to inform you that singletons work just great for me Smiley Having plastered them everywhere I then got on with finishing some games.

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

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

Cas Smiley

Offline theagentd
« Reply #9 - Posted 2012-01-23 09:11:57 »

I am pleased to inform you that singletons work just great for me Smiley Having plastered them everywhere I then got on with finishing some games.
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.

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2012-01-23 09:56:18 »

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

Cas Smiley

Offline Danny02
« Reply #11 - Posted 2012-01-23 10:45:29 »

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.
Offline JL235

JGO Coder


Medals: 10



« Reply #12 - Posted 2012-01-23 16:27:54 »

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.

Offline Cero
« Reply #13 - Posted 2012-01-23 17:13:30 »

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.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #14 - Posted 2012-01-23 17:29:11 »

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

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

Offline JL235

JGO Coder


Medals: 10



« Reply #15 - Posted 2012-01-23 18:04:42 »

#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
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.

Offline R.D.

Senior Duke


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« Reply #16 - Posted 2012-01-23 21:03:26 »

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 Cheesy
Offline JL235

JGO Coder


Medals: 10



« Reply #17 - Posted 2012-01-24 00:13:30 »

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 Cheesy
If you pick the good bits, and use them wisely, then it can often end up saving you time.

Offline R.D.

Senior Duke


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« Reply #18 - Posted 2012-01-24 03:10:38 »

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 Cheesy
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" Smiley 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".)
Offline ReBirth
« Reply #19 - Posted 2012-01-24 03:15:15 »

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

Offline lhkbob

JGO Knight


Medals: 32



« Reply #20 - Posted 2012-01-24 04:15:51 »

I think the takeaway is that singletons can be useful but that have some pretty serious downsides.  When you're programming on your own and are re-writing or not caring about re-usability, the problems with singletons usually do not outweigh the benefits so you can use them.  But if you join a big project with 20+ people working on it, a singleton might cause problems down the road for someone else, in which case you best avoid their use.

If you program for a learning point of view, to understand what works and what doesn't (including the problems of what works now vs. what will keep working as I design more of my game), I would recommend trying to solve your problem without singletons just so that you know other solutions for situations where you can't fall back onto singletons.

But if you want to make something fun that works now, do what is easiest and understand that you might have to change things later.  It's all about when you choose to pay the price, and how time affects that price.

Offline SkyAphid
« Reply #21 - Posted 2012-01-25 03:10:09 »

Thanks for all the input. Although, I don't think I'll make classes for each skill..seems a bit overkill to me.

The singleton is working for what I'm doing, and efficiency only matters if it works, but doesn't work fast enough. I don't need more than one instance of the class either, it's simply going to load some stats if the game is being loaded, or make some. Simple enough. They aren't referenced enough to even deserve their own individual classes, except for the player name of course, but still. I think it'll be fine, if I have problems, luckily, it's all written/organized code, and modifying it will never be a problem Smiley

I apologize again for being so touchy, it was a bad day. I'm sure we all have those. lol.

(Oh, and I didn't read the "tome" on asking good questions. I'll just make sure to be more specific and clear if that's okay  Wink)

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline loom_weaver

JGO Coder


Medals: 17



« Reply #22 - Posted 2012-01-25 04:10:39 »

Thanks for all the input. Although, I don't think I'll make classes for each skill..seems a bit overkill to me.

The singleton is working for what I'm doing, and efficiency only matters if it works, but doesn't work fast enough.

This discussion did veer off path into Singletons and I'll accept some of the blame for that.

In your original post you said that the singleton wasn't working and in your most recent post you're now saying it is.

What did you end up changing and what aspect of the Slick library restricted what you were trying to do?  Can you point us towards the API calls that were causing trouble?
Offline JL235

JGO Coder


Medals: 10



« Reply #23 - Posted 2012-01-25 05:41:47 »

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 Cheesy
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" Smiley No offense I can understand the arguement but I am not doing any scalable software for a large company. I'm doing a game.
If it's a tiny game, then I agree. If it's something that you will be working on for a few months, and will be measured in 10s of thousands of lines of code, then it helps to follow good guide lines.

I have tonnes of bugs in my code, which have been caused simply because I have changed something else where. Good practices can help to isolate potential issues, and make them more durable to change. It also helps to avoid that "oh, f*ck" moment when you realise you need to build something that doesn't fit into the current system.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #24 - Posted 2012-01-25 06:27:53 »

Unit tests are great for avoiding "breakage at a distance", or at least catching it very early.  I just can't recommend them enough as part of writing any robust codebase.

I hardly ever reach 10,000 LOC though: when I get near that point, I end up writing some abstraction or finding some library already written that lets me cut out huge chunks of my code and bring the LOC back down.  I suppose it's because I write most of my stuff in languages that don't require boilerplate (perl+Moose, python, scala), so things like getters/setters simply don't appear in the codebase.

Offline Roquen
« Reply #25 - Posted 2012-01-25 09:10:41 »

Quote
so things like getters/setters simply don't appear
Go go operator overloading!  The lack of is the real problem here. 
Offline R.D.

Senior Duke


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« Reply #26 - Posted 2012-01-25 12:06:16 »

If it's a tiny game, then I agree. If it's something that you will be working on for a few months, and will be measured in 10s of thousands of lines of code, then it helps to follow good guide lines.

I have tonnes of bugs in my code, which have been caused simply because I have changed something else where. Good practices can help to isolate potential issues, and make them more durable to change. It also helps to avoid that "oh, f*ck" moment when you realise you need to build something that doesn't fit into the current system.

To point that out. I do have an understanding for most langauge features, so mostly use Interfaces for a lot of things. Why? Because errors when changing a Interface diretly appear in my super nice IDE. I add the methods and stuff und voila. I never had the problem that I changed something and generated tons of Bugs Oo Sounds like there is something broken und your system in general...
To be honest I'm just a anti-Clean-Code dude Cheesy I can' split my method into 5 sub-methos which are private because a book says it's cleaner.
Offline SkyAphid
« Reply #27 - Posted 2012-01-25 12:41:20 »

Thanks for all the input. Although, I don't think I'll make classes for each skill..seems a bit overkill to me.

The singleton is working for what I'm doing, and efficiency only matters if it works, but doesn't work fast enough.

This discussion did veer off path into Singletons and I'll accept some of the blame for that.

In your original post you said that the singleton wasn't working and in your most recent post you're now saying it is.

What did you end up changing and what aspect of the Slick library restricted what you were trying to do?  Can you point us towards the API calls that were causing trouble?
Nothing with slick was wrong, it was actually just something that messing up the singleton externally. In which this was my own fault, and I assumed it my singleton was broken, as I've never used one before.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Offline ReBirth
« Reply #28 - Posted 2012-01-28 15:09:45 »

then, how about singleton use in handling sprite to save memory?

Offline UprightPath
« Reply #29 - Posted 2012-01-29 02:35:20 »

Singleton for sprites probably isn't the best pattern, especially since that would imply either one class that has access to all of the images or that you only need one simple set of images for the entirety of the game. Neither options sounds good to me.

Another option would be to use the somewhat similar 'Flyweight Pattern'. Which, in basic terms (And basically incorrect except as an analogy), is a Factory that holds a reference to several Singletons (Used to hold the graphics/sprites for a single thing). Then, everything that needs to get a Sprite would ask the Factory for that's Sprite Singleton, the Factory would build it (If it doesn't exist), then give what's asking it that singleton.

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (42 views)
2014-10-16 15:22:06

Norakomi (32 views)
2014-10-16 15:20:20

lcass (37 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (66 views)
2014-10-14 00:35:47

TehJavaDev (59 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (85 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!