#begin

Unity3D is well known for its low barrier to entry. A total newby can get the infamous ‘Roll a Ball’ tutorial up and running within a few hours. All without much coding involved. Unity’s editor and component based architecture even seems to promote drag and drop style development aka ‘sleur en pleur, in Dutch. At least, at first glance. There are lots of utilities and pre-made components to get the basics done. Think of audio sources, character controllers and animation systems. Combine this with the visual programming Unity exposes and you could come a long way without ever writing a single line of code.

But, at some point developers will be blocked by the fact that their custom behaviour is not available through built-in utilities, AssetStore downloads or it cannot be easily expressed in visual programs. At last, its time to open up a text-editor, or better yet, an IDE. Roll up your sleeves and write some code. To me, the actual fun part of game-development.

But where do we start? I’ve even seen very experienced developers struggle with starting to write code in Unity. I often get asked questions like; “where, or what is my main” or “What is the entry point?” and “How do I do dependency injection?” These are valid questions with-or-without IOC container. To add to the problem; there are countless tutorials out there that promote bad coding habits. Encapsulation is not well respected, dependency injection through magic serialised inspector exposed fields is the way of the game and last but not least managers, controllers and / or singletons are at the centre of their design. This leads to a project being very difficult to test, maintain and evolve.

The fact that there is no clear entry point to a Unity3D application drives developers onto a path to use singletons as a core abstraction of their projects. Singletons however have been scrutinised relentlessly ever since their identification in the original GOF book about design patterns. Problems are well known across the software industry, including gaming. So why then are singletons such a prevalent force in Unity3D apps?

 

The singleton side-effect

In my honest opinion I think its the fact that Unity3D does not provide a clear entry point to hook into, is the root cause of this viral spread of Singletons across Unity projects. Yet, this is no excuse since developers are intelligent enough to come up with a way to create their own entry point. Simply said; add a GameObject with a ‘Main.cs’ component attached to act as an entry point to the application. There are several other ways of solving the entry point problem but I’ll keep that for a separate discussion.

Another problem is that most, if not all tutorials you will find the internet will have some sort of Singleton at the core of their design. You’ll encounter ‘MenuManagers’, ‘PlayerControllers’ or ‘MyDataBaseSingletons’ everywhere you look. Even in some of the official Unity3D tutorials you can find them. I once had a conversation with some developer that worked at Unity and he said that the tutorials are meant to get people hooked onto Unity as fast and as easy as possible. If their first experience with Unity is: “Wow, this is really easy. Look, I made the ball roll” the tutorials have succeeded in their goal. Its to attract customers and sell licenses, not teach devs good coding practices.

And I even think there might be a deeper practical problem at work here. Sounds deep, right. Bear with me, I’ll explain 😉 Unity’s market share on Google Play and the AppStore is monumental. Most of these games are of the casual or ‘hyper’ casual kind. There are studio’s pooping out multiple brain numbing endless runner games per week in the hopes to land only a single critical hit. The bigger part of these games will not survive and probably the ones that do, won’t stay very long due to the saturated market.

This leaves devs to quickly churn on games not caring about their design since maintenance is simply not a concern. Yet as their ‘seniority’ grows while maybe having scored a hit (or two) they will start teaching junior developers the crux of the craft, creating tutorials and repeating the vicious cycle of shitty software design in Unity3D apps.

But, these are just my thoughts and what do I know? I’ve done technical interviews with developers that only worked in the (hyper) casual market, and I feel that these are the developers that would match with the saying: “Having one year of experience, just repeated over 10 years”. Meaning; having worked for 10 years without measurable growth. Which is pretty sad to be honest.

 

Singletons are bad m’kay!?

As design patterns gained popularity during the 90’s the adoption of the Singleton probably skyrocketed. Why!? Well because its a very simple design pattern and enormously powerful. Global access brings (over 9000, unlimited) power but great responsibility.

Singletons have suffered from a lot of scrutiny over the past 30 years or so and much of it is well deserved. Singletons although powerful and easy, can create many problems. The well known ones are issues with testing, dependency management and performance. Singletons also often evolve into this Frankenstein abomination of accumulated responsibilities where even the great flying spagetti monster in the sky does not have enough tenticles to keep it in check. If you know your SOLID principles your spidey senses should be tingling right now 😉

Personally, I’m in the “it depends” camp. I think a small strategically placed singleton can be very helpful. Yet still I will do my absolute best to avoid any use of a singleton. There are also the fundamentalists that will say singletons are always bad and yet, they will promote the idea of an Inversion of Control (IoC) container. Wake-up call: an IoC container is a Singleton! That being said; I rather have neither in a Unity context.

In DotNet land, IoC containers are the normal cause of doing business. If you’ve ever written a DotNetCore backend application you will be familiar with the start-up procedure and its builder pattern to setup such IoC container. Another example is (android) mobile apps being fully dependent on IoC containers like Dagger, Hilt or Unity (not the game-engine). And Unity3D of course, has none of this build in.

 

The ultimate admittance to failure

The main goal of a Singleton is to provide global access to some data or functionality by leveraging a single static instance. The most fun and ironic part of singletons is that there are often, if not always, more than one. It’s like the Sith they are. What’s ironic about this is that IF you use a singleton, you only ever need one. There’s always a way to access a singleton so you can always piggyback new objects onto it. But I suppose that having a singleton in the code base somehow justifies adding another.

Don’t ever do this; but if you follow the “Service Locator” Pattern you could make the service locator itself a singleton, but any of its registered services are normal classes. But you should try to avoid this because the service locator will become patient zero in spreading viral dependencies across your project. Since everything and everyone can simply fetch a reference to some service, dependencies will spread. Proper discipline and some static analysis could avoid that but my personal preference is to solve the singleton problem with proper software architecture.

And for exactly this reason I think that having some sort of abstract base-class for a Singleton is the ultimate admittance to failure. It just too inviting to just derive another class and simply add a new Singleton to the ever growing list.

In suspect that every Unity3D developer has used or at least seen such a base-class. There is this specific template circulating around on the forums which provides an abstract, thread-safe base-class that exploits generics. Indeed, what a wonderful world.

I’ve heard multiple people defend this specific use-case by saying that: this abstract base-class is useful when you put in in some core layer of your domain / application. Maybe even a dedicated assembly. But this exactly proves my point that it will promote a wild growth of Singletons. I will answer that by asking them: *if you already accept that there is some dependency that everything would depend on, could you think of an alternative?*

There are many answers to that question of course. Some might involve IoC containers, service locators, event-busses and maybe, just maybe, good old manual dependency injection.

 

Singletons… are dead

So how then do we eradicate this pandemic of Singletons that has been spreading across Unity projects? Well, the answer lies in solving the entry point problem; when we have an entry point into our Unity application we can use that to initialise our main components and from there spread the needed, ***abstract*** dependencies elsewhere, exactly as we are used to in any other kind of software application.

So next time I’ll discuss some of the strategies to tackle this problem to finally get rid of the Singleton plague.

 

#end

01010010 01110101 01100010 01100101 01101110

Hey, sorry to bother you but you can subscribe to my blog here.

Never miss a blog post!

You have Successfully Subscribed!