I am currently in the progress of refactoring my entire code and the singleton approach seems the easiest to me as this is a tilebased RPG game ala Zelda and there is at most ONE instance of the game. There is a whole lot of hate against the singleton (SO hates it) and I can't seem to think of a better way to manage everything in my game. Instead of worrying all the time that I may have created a duplicate of my rendering class or my sfx class I can instead focus on making those classes much more powerful.

One of the downsides I see is that it makes for very sloppy code, the game will work IF and only IF you order the code in a certain way so as to not call something that has not yet been set (or do nullchecks every...sloppy). Are there any other downsides? What is a better way to manage resources and entities and logic and rendering and sfx? What are your experiences with singletons?

What are the odds that you will accidentally create a new rendering system, audio system, or game instance? I would guess it would be pretty low and so it shouldn't be something you spend a lot of time worrying about.

The order of operations issue you raise will happen whether you use singletons or not.

The issue seems to be more one of convenient access. You have these "system" classes like rendering and sound and you need to be able to get at them easily from anywhere in the code base.

The problem I have with singletons is that they become global variables and as such they tend to get used everywhere. This means your classes may have lots of dependencies and becomes harder to reason about. They can also reveal too much about how something is being done. It is sometimes better to better to hide "System" classes and reduce their scope.

As an example, my game uses message passing. So I had a base Event class from which concrete events (ExplosionEvent, ShipArriveEvent) inherit. These were all managed by an EventSystem. Because anything could send an Event, I made the eventSystem a public static field in my game class. I used it like so:

A couple of issues:1. The Missile (and anything else that sends an Event) is coupled to EventSystem. 2. The Missile is also coupled to MyGame because it needs to be able to get the eventSystem reference. 3. Why does the Missile care about how Events are sent?

So I made a few changes. I created a private static EventSystem field in the base Event class and added a public static setEventSystem() method. I also added a "post()" method to the Event:

// Posts the event to the event system.publicvoidpost() {Event.eventSystem.addMessage(this); }}

// In my game initialization code I have something like thisEventSystemeventSys = newEventSystem();Event.setEventSystem(eventSys);

// So now back in my missile class I use it like:newExplosionEvent(ship,xPos,yPos,damageScore).post();

The dependancy is hidden within the Event class. The only thing senders care about is the specific Event they are creating and, semantically, "post()" exists at a better level of abstraction than "eventSystem.addEvent()".

How big of a difference does this make? In this one case, not a huge difference, but as globals and systems pile up, it can start to add up.

I don't know if singletons are the way to go, and certainly aren't the simplest way, but I am using singletons myself. I handle this similar to a way minecraft handles blocks. However, unlike minecraft, I use two classes; an Entity class, which holds information, and an Abstract Controller class, which does the logic.

The abstract Controller has a few static variables/functions. Here is the basic code:

Now, anytime we make one of our singleton controllers, it will be kept in our array of controllers. The last things to do are make something for the controllers to act on, and make the controllers act on it. I handled this by first making an entity class that has its controllers id:

You should avoid singletons wherever you can.The singleton is reasonable called an anti pattern.

How would you unit-test a singleton?

Who actually unit-tests game code anyway? And what makes unit-testing a singleton particularly difficult? The reasoning "do not use singletons because it is an anti-pattern" basically says: "do not use singletons because do not use singletons", which is no reason at all.

I use singletons & static functions for certain things and they work just fine. Practice overrules theory as far as I'm concerned. Some things I found singletons to be useful for accessing a global asset manager, the graphics and sound modules, preferences, and some other stuff that needs to be accessed everywhere. For these things using a singleton is much cleaner and more manageable than passing around masses of objects everywhere around your code-base.

That said, like anything in coding you have to take care in using singletons. I try to avoid singletons that allow changes to game state (e.g. an entity system that may be accessed anywhere), as this tends to make debugging much more difficult.

You should avoid singletons wherever you can.The singleton is reasonable called an anti pattern.

Any pattern or language construct can be an anti-pattern when used badly or in the wrong circumstances. Singletons are often used for the wrong reasons or implemented incorrectly, but they do have their place, a good example is to access the 'global' sound system when using OpenAL.

When it comes to unit testing you need a clearly defined state of the class you want to test.When not using a singleton, a simple

1

newFoo();

provides you a fresh instance and a clean state.

But how can you ensure that for a singleton?By definition there is only one instance of it and you can not be sure that it's state is what you expect it to be which makes testing it very very hard and error prone.So your only chance would be to implement a method to reset the state of your singleton which again is error-prone.

Everybody who likes to save development time and raise the overall quality level.

Perhaps if you're working in a (large) team and in some specific use-cases this is true. For me it just feels like keeping 2 rapidly evolving code-bases in sync (the code itself and the unit test code meant to test it), resulting in a load of extra work and very little extra value. Maybe for someone who has a different approach to coding it works better.

Perhaps if you're working in a (large) team and in some specific use-cases this is true. For me it just feels like keeping 2 rapidly evolving code-bases in sync (the code itself and the unit test code meant to test it), resulting in a load of extra work and very little extra value. Maybe for someone who has a different approach to coding it works better.

I think you're making a mistake in considering unit-test code to be 'extra work' and 'little value', this is often the response I get from new or junior engineers (not meant to be a slur btw!) who have yet to have the epipheny moment. Personally I now feel nervious (and dirty ) if I have code that doesn't have comprehensive test coverage.

There are some obvious positives to unit-testing:

- It's a lot easier to fix any bugs or design flaws when the code is fresh in your memory, rather than finding them days or even years later.

- Sections of code are often inter-related (especially highly coupled code like deep inheritance hierarchies), you make a change here and might inadvertently knacker something in an unrelated section over there, how are you going to ensure all your code still works after making changes without a test suite?

But there are some more subtle benefits as well:

- If you develop the unit-tests and code in parallel you are effectively exercising your design as you code, i.e. you become a sort of 'user', and can therefore spot and resolve any design flaws sooner rather than later. I've often found myself thinking "this sucks" and completely redesigning a class or package.

- Unit-tests are also essentially documentation for how to use your code, again handy if you come back to re-use a chunk of code and need a refresher on how it works.

Of course if you're a hobbyist then you can do what you like but I'd advice you to give the above some consideration. Try it, you might just like it.

Of course if you're a hobbyist then you can do what you like but I'd advice you to give the above some consideration. Try it, you might just like it.

Haha, you tell a convincing story For my hobby project which I'm working on alone it still seems to be too much overhead, but especially on large complex projects with multiple people working on it I can see how it would be great (maybe even indispensable). I may play around with it a bit.

I prefer not to use singletons/static methods because it makes my code less OOP-like and more procedural which (for me) is harder to reason about. I have never personally had a case where I accidentally created additional instances when I only mean to have one. My biggest driver is that I have some service that is needed all over the place and a public static reference is just very convenient. I have not found an alternative solution to this that was satisfactory other than to try and design my code to limit the scope these static fields/methods need to have.

At first, I thought unit testing was a bunch of bologna. However, there are two types of errors in coding. The first is syntax, which is the errors that you can find because your compiler says so. The second type is logic, which usually means that you have to set up breakpoints and search through to find the error yourself.

Unit tests fall into the latter category. They allow you to snapshot your code so you can find out when something is not working logically. The time unit tests become very useful is when your project becomes very large and you want to change a small section. Those tests will prevent you from having to use breakpoints completely (in some cases) and get your code working faster.

I don't recommend it for small projects, but for any project that is very big. Writing those tests can become very beneficial in saving time looking for logic breaks.

In most cases, you can use static instead of singleton.I use static where possible because it's less typing. But if singleton became more convenient in a certain situation, then I would use it for that instance.

In the end, do what's convenient for you (unless you're working on a team ).

Don't worry about following OOP rules if breaking them results in better code/coding.

Programming standards are a lie. Using combinations of different standards results in the nicest code.

One of the nice effects of sticking to a unit testing regime is that you tend to design your code for testability. By forcing a little self-contained use-case into every unit (which usually means every public method that isn't just an accessor), you try to avoid coupling and sneaky side effects, which are both great qualities for any codebase.

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