I see the topic of choosing the “right language” when it comes to games brought up too many times in discussions all over the internet. The argument is usually between C++, C#, and Java. People do get religious about their favourite languages. At its heart this is an inherently flawed question, because the real decision should be on what framework or engine is best suited for a particular game, and that choice will usually dictate what language to use. Of course, the languages supported by a specific framework or engine can definitely be an important factor that may affect your decision.
And the truth is, assuming you have a choice, Java comes short in the race. When this is pointed out, some people erroneously claim that it’s a matter of “opinion”. That’d be true if it wasn’t so easy to prove that Java is ill-suited for games development. “You’d use the right tool for the right job” is very noble statement, and one that applies a lot in any kind of software development. But it’s also very abused and it gives the false impression that Java is sometimes the right tool.
Moreover, this article will focus on comparing C# with Java and barely mention C++ at all. C++ is in a whole different league; it’s much harder to write, but provides ultimate control over areas in which performance matters. The thing is, you would indeed use the right tool for the right job. And it’s true that there are many cases where one would prefer to use Java over C++ because it’s just much easier to handle. In that case, C# should still be preferred instead. One could even use C# in some cases in which C++ would have been preferred over Java.
Finally, I am not denying the fact that C# (or at least as we know it) wouldn’t have existed without Java. Java was the innovation when it came out, making programming a lot less painful than it was at the time. Most of Java did make sense, but many of the decisions about its design proved to be mistakes over the years. C# was Microsoft’s creation that came as a very balanced approach that included a lot of the good features of C++ that Java discarded, while retaining at least the same ease of use.
A very common misconception is that Java is more cross platform and C# runs only on Windows. This is not true, or at least, not anymore, and at least not on platforms that matter. The .NET platform is no longer a Windows-only platform, and in fact C# actually has better support on any device that can run games. And this isn’t just about the Mono platform (an open-source implementation of .NET), but as of April 2014 even the C# Microsoft compiler itself is open-source.
However, mobile support for C# is still not free and you need a Xamarin license for that. I was hoping that C# going open-source would change that. Unfortunately, that hasn’t happened yet. If you are on a low budget, then you have no choice but to use Java (or another free solution). But, as a language, this doesn’t make Java in any way superior.
Note that neither C# or Java are as “cross-platform” as they appear to be. Not only do they still need specific binaries for each platform they’re to run on (you’d use a different OpenGL wrapper on Windows than you would on Mac or Linux), but you still eventually run into compatibility issues where the same code runs differently on different operating systems. So, choosing any “language” because it’s cross-platform makes no sense. It all depends on the frameworks you are using and whether or not they’re supported on the platform you wish to publish to.
Too long; didn’t read
This article can be summed up by the following points.
- Java provides no relevant advantages over C# in games programming.
- C# provides extra features that are essential for mathematics and graphics programming. These features not only make C# easier to use in those cases, but also allow C# to outperform Java in certain situations.
- C# provides even more features on top of those.
In other words, there are valid reasons to prefer C#, but no reasons to prefer Java. This is an one-sided race. You can read ahead for a more in-depth explanation if you are not convinced.
Java provides no relevant advantages over C# in games programming.
Can you think of any? If you can, then please leave a comment. I will update the article accordingly. In fact, it seems that game developers will usually choose Java for misplaced reasons.
Bad reasons to choose Java
Java is still the most popular language
The fact that a language is more widespread than another does not mean that it is in any form better. Companies prefer to use Java because it is a tried technology that works, and it’s allegedly easier to find Java developers than C# developers. Again, this doesn’t take games into account, as the companies that use Java are mostly interested in business applications. Most game companies would prefer C++ or a knowledge of the framework they use.
Learning Java just because companies prefer Java developers
That’s again a bad idea, because most companies couldn’t care less about non-industrial experience in any language. Like it was pointed out before, the technology or framework you use is much more important than the language, and it’s what actually takes the most time to learn. There are heaps of programmers out there with actual industrial Java experience in technologies the companies are looking for. You won’t have an edge over anyone.
Starting with Java because it’s “easier”
C# to a beginner isn’t that much different. It appears to just use a different set of libraries and a slightly different syntax that is closer to C++ than Java. Java has less of the features that a beginner cannot understand, but that’s it. Those features are not invasive and are mostly optional.
In fact, Java is not easier. It’s much harder to both read and write, simply because it lacks many of the convenient features of C#. It is unnecessarily verbose and highly inefficient, providing no proper ways to mitigate that.
Java encourages good programming practices, C# does not (false)
One of my favourite programming quotes (I don’t know who said it) is that “there’s no programming language that can prevent a bad programmer from writing bad code”. And that quote is absolutely true, judging from the Java code that I have to deal with every day. For a language that is allegedly not adding new features because they’ll be misused, people sure do manage to write loads of bad code.
C# does have more features than Java, such as the lovely properties and operator overloading, that the java people seem to have an issue with. “If we allow someone to override the + operator, they might abuse the feature and have it do something other than addition”.
This is absurd, as operator overloading is a very safe feature to use correctly in C#, unless you are actively trying to mess things up. I do agree that it’s much more easier to misuse in C++, but C# does things right; for example, C# prevents you from overloading the += operator, you only need to override the + operator, and a += b will automatically call a = a + b for you. (Admittedly, this adds a small overhead that would have been avoided with a += operator. If it were up to me C# would have allowed overriding it and supply a default implementation).
The same applies to every extra feature C# has. Operator overloading is just an example. Saying the extra features of C# are a bad thing is the equivalent of saying that hunters should use nerf guns in case they shoot themselves in the foot. Besides, anyone who intentionally misuses operator overloading to do something other than addition shouldn’t have been a programmer in the first place – the project was doomed from the beginning.
You wish to write code for Android only.
The Android SDK is not meant to be used for games. You’d be better off using a cross-platform solution. In fact, even if you are set on using Java, it’s better if you just use LibGDX instead, which is a very excellent cross platform game framework that (unfortunately) uses Java.
Good reasons to choose Java (for games)
There are actually valid reasons to choose Java, but they’re not because it’s in any way better than C#.
Free mobile support
As mentioned above, a free C# solution for mobile games is currently not available. Unity is a notable exception, but it doesn’t use “pure” C#. I expect that this will change in the near future, now that C# has become open-source. Again, this does not make Java better as a language.
No longer applicable.
You are working with existing code
It goes without saying, if you are already working on a project that you’re now deeply into, or you are working on an existing code base, it’s a horrible idea to give it all up.
You have a lot of experience with Java
This is both a good and bad reason, depending on the context. It’s mostly bad, because it means you are just unwilling to get out of your comfort zone and learn a technology that will be much better to use. However, if you’re just beginning at game development, it might make more sense to start with something that you’re familiar with.
Good reasons to use Java (not applicable for games)
It is true that using Java does have some advantages over C#, due to the fact that it has been around longer and it was open-source since the beginning. However, those reasons are not applicable for games. I thought it would only be fair to mention them.
Java supports other JVM languages
I find this an ironic thing to brag about in Java’s favour, but it’s true that other languages have been developed for JVM that have a lot of features not available for Java (most of which are already available in C#), that you can use alongside.
I still didn’t get the chance to properly learn a JVM language like Scala, so I wouldn’t be surprised if I end up liking it more than C# (my current favourite). C# should still be a better language specifically for games, but I’m willing to give this the benefit of a doubt.
More open source frameworks
It does provide more non-game-related open source frameworks, mostly because it’s been around longer. Although, in my opinion, Java’s ecosystem is a huge mess with lots of outdated/deprecated frameworks.
C# provides extra features that are essential for mathematics and graphics programming.
There’s one thing that Java desperately needs before it can even pretend to be a good option for game programming. And that missing feature is custom value types. This is such an important concept that it unlocks so many possibilities. All other points in this section have to do with that in one way or the other.
In C#, Value Types are objects that are declared with the struct keyword instead of class . The difference is that even though they look like classes, they act more like integers and other primitive types. In fact, C# defines primitive types as structs. This is in contrast to Java, in which integers can never act as objects (unless you employ ugly wrappers) and where you can’t define your own primitive types.
Structs are not allocated on the heap (which means no garbage), and each time you pass them around they get copied instead of referenced; just like integers. This might not sound like a big thing, but it makes all the difference in the world.
They are definitely not a replacement to classes – on the contrary, most types should still be defined as classes. Relevant article here. If you use a framework or an engine like Unity, there are already types that are defined as structs, and a great example of that is the Vector3 type. When structs are used appropriately, the benefits are numerous:
Continuous memory allocation
- Faster iteration over elements
You get cache locality and avoid the cost of an extra reference.
- Less memory usage
An array of a class that contains a single integer will consume overall double the memory on 32-bit applications and triple that on 64-bit than its struct equivalent.
- No need for intermediate buffers
You can send your arrays via OpenGL directly as buffers, without having to copy everything.
Using a struct that only contains a single integer should not, in theory, be any more expensive than using an integer. Creating it allocates it on the stack, which, aside from other benefits, means they will be quickly destroyed as soon as they get out of scope. In other words, structs create no garbage, allowing you to minimize the total amount of garbage generated by your code.
Better immutability for members, aiding software design patterns
Still not as great as immutability in C++, but it’s a step forward. I don’t think it was exactly planned, but it’s a nice side-effect you get when using structs.
I will admit that sometimes it’s not so nice; for example, C# won’t allow you to change members of a struct that is returned via a Property. What you’ll need to do is pass it to a temporary variable, modify it, then assign it back:
Vector3 example = foo.Position; //Position is a Property and not a member
example.X = 10;
foo.Position = example;
This seems counter-intuitive, and to a point it is. If you just want to change individual X, Y or Z coordinates for a 3d vector, you’d either have to expose individual Properties for them, which change the vector directly, or expose the whole vector as public.
However, you also get one positive side-effect: The users of your class may not change the Position value without you knowing and handling it accordingly.
Possibility for intuitive mathematical types (like vectors and matrices)
They severely improve code readability and also perform much better than any current Java implementation. This might not be an issue in the simplest of 2D games, but the lack of proper math support in Java will start to mess with your head when you get into 3D graphics and physics.
Value types are not at all a gimmick that is only good in theory. C# makes sure to provide excellent support for them, and they don’t feel like an afterthought added to the language for no reason. With them, you get some nice bonuses:
Generics that are optimized for value types.
In Java, not even integers can be used in generic collections; you’d have to box them using the Integer class.
Nullable types, denoted by a ? (i.e int? is a class that may or may not contain a value)
In Java you can use the wrapper classes, but there is no need for nullable types if structs aren’t supported.
Value types can be passed by reference using the ref or out keywords.
Again, java can’t even do that for integers. Boo, Java, boo.
Operator overloading makes more sense.
One of the valid uses of operator overloading is to support mathematical operations between custom types. Those operations typically return temporary objects. For example, the expression int i = 2 + 5 first creates a temporary integer that is the result of 2+5 and then assigns it to i.
Likewise, working with 3d vectors should have similar results. Since structs aren’t allocated on the heap, the temporary result of an addition won’t produce any garbage (assuming the implementation of the addition itself doesn’t). Even if Java did support operator overloading, it’d be a bad idea to use it, as that would create unnecessary objects on the heap.
I can still go on and on about all the good things we get from structs. And if that’s not enough, we can even go one level deeper and use pointers and stack allocation for reference types. Although, to be honest, I’ve never used that myself in C#.
To summarize, C# provides MUCH better handling of memory. This is an extremely important feature for efficient games programming.
C# provides even more features on top of that.
I won’t waste my time getting in detail, because this is the part that has already been exhausted online via other sources. There are numerous articles that explain why C# is simply better even for general non-game applications.
A lot of these features are simply syntax sugar (i.e Properties), others are just much better than Java equivalents (i.e C# LINQ vs Java Streams). Here’s a non-comprehensive list, in no particular order, that mentions some of the the features that Java is lacking:
- Custom value types (structs)
- Unsigned numerical types
- Much less verbosity and boilerplate code
- Generics optimized for value types
- Generic constraints
- Better handling of string equality
- Arrays can act as higher-level sequences
- Lists act like arrays
- Operator overloading
- var keyword
- Reference parameters
- Extension methods
- Attributes instead of annotations
- No checked exceptions
- Partial classes
- …and more
I’ve seen people say that “a good programmer can make a game with any language”. That’s not entirely accurate. A more correct statement would be that “a good programmer can learn any language”. And yes, you can use Java if you want (Minecraft being the best example), but that doesn’t mean it’s a good idea!
Java is unsuited for games, because of its inability to give you any sort of proper control over memory. On top of that it’s horribly verbose and the people behind it actively avoid adding new features to the language.