One of the most common questions I see in various forums from people new to game and simulation programming is which language they should choose. If you already know a programming language but are just getting started in game development, my general suggestion is to just use the language you know best. If you don’t know a language yet or you do but you’re thinking of picking up a new one for an upcoming project, then read on because I’ll be going into some of the features of languages that can impact your project. Programming languages are a complex topic, but I’ll try to avoid going too deeply into the nittygritty so if you’re new to programming, hopefully you’ll walk away with a better understanding of the factors involved in picking a programming language without being completely lost. Because there’s so much to discuss (and the first draft was massive), I’ve broken it down into a 3-part series.
I should point out that these suggestions are all based on writing a game completely from scratch. In other words, these features will affect the game engine you write. If you plan to use a pre-made game engine such as Unity, Unreal, Stencyl, etc. then the language choice is pretty much out of your hands. This is actually one of the reasons using an existing game engine isn’t always the best choice for some projects, but that’s a conversation for another post. If you plan to pick up a game engine, then you’ll be using whatever language that game engine uses.
There is No Best Language
Let’s start with the question I’ve seen a thousand times online: “What’s the best language for game dev?”
Answer: “There isn’t one.”
Like any software, different languages have different features that could help or hinder your game development project. It depends heavily on the type of game you have in mind and where you plan to run it. Game development resources have exploded over the years, so no matter what language you choose there’s probably at least one game development library available to make your life easier. If you’re just looking to learn about game and simulation development, don’t let picking a language stand in the way of learning the craft. Once you have the basics, you can always move on to a new language that better fits your dream game. The algorithms and concepts behind game development are rarely language-dependent, and learning them in any particular language won’t bar you from using them elsewhere. They just might need to be translated a little.
Of course, this wouldn’t be a very interesting post if we stopped there. Even though most algorithms can be written in any language, they can still differ in how they run your game. As game developers, it’s worth knowing the benefits and limitations of languages and how they could potentially impact your game. Minecraft is a prime example of a game that has bumped up against the limitations of its language over the years, especially with the growth of the Minecraft modding community.
Language Type: Compiled vs. Interpreted Languages
Programming languages are designed to be read and understood by both humans and computers, but doing so takes a little compromise on both sides. We need something that can be analyzed and written by a human, but also understood and executed by a computer. Code might look like a foreign language to people new to programming, but they’re really just a series of instructions for a computer to follow. In a compiled language, we take the code we’ve written and translate it into instructions a computer can follow. This process is called “compiling.” The result is a file called an “executable” that contains a set of instructions for a computer that can be loaded into memory and run by the operating system on a processor. The problem with this is that any executable that’s created will only work for the operating system it’s compiled for. In game development, this means compiling your game on Windows will result in an executable that will only run on Windows systems. This is made worse by the fact that one often can’t just compile the same code for a different operating system. Different operating systems may use different instructions to accomplish similar things. For example, while Windows uses the Winsock library for network communication, MacOS and Linux use BSD sockets. Both libraries provide instructions for network communications, but the instructions and methods differ slightly. This means having to write two different versions of your networking code in order to compile it on both Windows and Linux. It’s possible (and even common), but it’s also more work.
Interpreted languages are a more recent invention (relatively) and work differently. In these systems, the code isn’t compiled into machine instructions. Instead of loading an executable into memory, the code is translated by an interpreter which feeds the resulting instructions to the operating system through a virtual machine. This makes interpreted languages extremely portable. You can write the code and move it to any operating system that has an interpreter & virtual machine (the two usually come together) for the language without worrying about OS-specific instructions. This portability does come at a cost though. Because interpreted languages don’t generate instructions that can be executed directly by the operating system, we have to use a different way to tell the processor what to do. This is done through a virtual machine. The process looks something like this:
- An interpreter compiles the code into a series of instructions that the virtual machine can understand.
- The resulting instructions are loaded into the virtual machine.
- The virtual machine executes the loaded instructions using its allocated resources.
The virtual machine acts as, well, a virtual computer. It maintains its own set of resources and processes instructions much like a computer would process an executable but it exists in a computer system’s memory and uses its resources to operate. It adds an extra step between the code and the processor because the virtual virtual machine effectively translates the virtual machine instructions into instructions executable on the processor while the program is running. The virtual machine also requires resources to run in addition to any resources required by the program its running, leading to increased overhead. As a result, interpreted languages tend to run a little slower and use a little more memory than compiled languages.
From a game development perspective, one of the other roadblocks to game development with interpreted languages is the virtual machine itself. Because interpreted languages require a virtual machine to run, your users must also have the virtual machine installed to play your game. This means requiring your user to download and install the appropriate virtual machine. It might seem minor, but in the competitive world of game development, even small obstacles to your user’s experience can have a big impact on the number of people who play your game.
I should point out that the reality of compiled vs. interpreted languages is actually much more complex and nuanced than I’ve presented here. If you look online, you’ll find plenty of discussions about wehther or not any particular language actually counts as interpreted or not. This is just meant as a general introduction to the topic to help inform your language choice. Join us next week when we look at the second major feature of a language: memory management.