Programming and how you are doing it wrong
Dobryy den’ my fellow game makers, game enthusiasts and programmers! This is Marco from 2GuyGames, a young startup with big dreams and a bigger ego. In our past articles we already talked about our general plans and goals. Today I want to get more into detail about the programming side of things. There are a lot of issues with the craft of programming today. In this article I will lay out what problems I see and how we at 2GuyGames want to solve them. So let’s get into it, shall we?
I am a programmer with some 10–11 years of experience. Half of that time in professional positions. I worked at a couple of companies (gaming and non-gaming), as a freelancer and (will soon) have a master’s degree in computer science. I can rightfully say that I have a solid theoretical and practical background when it comes to writing code. There’s one thing I came to realize about programming in all these years. We suck at it. I suck at it, you suck at it, the industry as a whole just cannot program jack shit. Especially the gaming industry.
Why do I say that? Software generally works pretty good, doesn’t it? Well, mostly. It’s true, most of the things we create, work reasonably well, but is that really enough? Surely you have seen a meme or two among the lines of “My code doesn’t work, I don’t know why. My code works, I don’t know why.” We’ve all been there. It’s getting better with increasing experience, but the bugs never disappear entirely. When coding, a lot of what we do is similar a shot in the dark, hoping to hit the target. In fact, we miss all the time. Think about it. Do you really know how the change you just made will affect the software’s functionality? Can you accurately predict its effects on the software you are developing? No. No, you cannot. It is impossible after crossing the thousand plus lines of code border. Why can’t we do it? Because code is complex. Because there are dependencies that we are unaware of. Because we don’t know what Dave next door is doing and how he’s going to take a huge dump in our code base.
So there are two problems right there. Too much complexity, too little communication. How can those be addressed? Let’s start with the easy one, communication. Why is it so hard for programmers to communicate? Well, we are programmers for Pete’s sake. Have you ever heard of someone becoming a programmer because they like people? We like machines, we like making things. However, this alone will not hit the target. Programming is a team effort. Unless you are a genius — which you are not — creating something of value demands teamwork. So how do we practically go about improving our communication? Regular meetings are one idea. Not that kind of meeting you are thinking about now. We don’t want non-programmers sitting around with us. They block us. Instead, sit together with your team of programmers and talk about the software you are developing. What does everyone do? What work is coming up? Does their work collide with yours? It is OK to get technical, that is what we are here for. Doing a stand-up meeting everyday is a good start. Make sure everyone is actually talking about how they are doing and not just saying what the management wants to hear. Even if you don’t meet everyday, keeping taps on what your colleagues are doing is very important!
OK, great, now we work as a team. How do we cope with code complexity? To answer that, we need to look at what mainly causes code complexity. There are several reasons. You might say: “Well, code is just complicated by design.” but in my opinion, that is actually a very small part of it. The more you write, the more complex it gets. Yet, there are countless countermeasures at your disposal. First and foremost, you should have a solid architectural design. This design heavily relies on the product you are developing. So the product should be equally well thought out! No, the software architecture is not done once you hand it over to your supervisor. Just like your code, it should be maintained, extended and refactored where necessary. It should reflect what your software ought to look like at every single point in time. Your team also has to be on board with it. The best architecture isn’t worth the paper it’s been written on if nobody adheres to it. What is important for the whole product? Does it have to be very fast? Does it have to work in real-time? Does it need high responsiveness? Everybody in your team should have a picture of the software you want to build. This becomes even more important when your requirements change (which will change). Your architecture then has to change as well, and every member on your team has to adapt. It is important to have a deep understanding of the product you are creating, and you all must be aware to plan possible changes. In short: You have to be prepared! You must have at least some idea what your supervisor demands tomorrow or in a month from now, and you have to develop a plan for it actively. You are making a piece of software that reads in XML-formatted data? Better expect the day when you are told, that it should be able to handle JSON-formatted data as well. And be accurately prepared by having an architecture which can handle different data sources by design. You create a strategy game, where the player has the choice between three different civilizations? Better create a design that later allows to easily add more. Early awareness and preparedness for changes will make the shift less painful and time-consuming.
Another issue that makes code unnecessarily complex is the near fanatical obsession with optimization. So-called “optimization” often makes code unreadable and hard to understand — in short: unchangeable. Now, I will let you in on something someone somewhere should have told you a long time ago: The quality of code is not measured in execution time. The optimization you are currently doing? Unnecessary. I can tell without looking. There are only a handful very specific cases where improving your code’s performance is absolutely necessary. So if you are going to make optimizations, ask yourself: What are you optimizing? Is it execution time? Is it memory use? Is it throughput? What trade-offs are you making? What are your boundary conditions? What is the value of the number you are trying to improve and what value should it have? Is this even the right place to start, i.e. the bottleneck? If you cannot answer any of those questions, don’t even start. Instead of optimizing execution time, optimize readability. Your code is written once, but will be read dozens of times. You may feel very smart when you write code that is hard to read (I am looking at you, Python). However, when faced with unreadable code, no one will whisper with a gesture of admiration “Wow, the person who wrote this must be so smart!”. Rather, the reaction will be among the lines of: “What piece of shit code is this what kind of idiot would even do such a thing?!” You may think the piece of code you just wrote is written in stone. It will eternally be in the world and outlasts mankind itself. It will not. People come and go and so does code. Code is not necessarily deleted because it is bad, but because it is no longer required. So make it easy for people who will change it, will you?
There are a lot of measures that assess code quality. Readability may very well be the most important and universal one. Other equally important measures are changeability and maintainability. In my opinion, these heavily rely on readability. Code that cannot be read can neither be changed nor maintained. The measures of security and efficiency are far more specific requirements and of less importance for many projects. Making your 2D, single player, roguelike secure? Probably irrelevant. Making it efficient? Unless you are making a mobile game and outside of doing something outrageously stupid (like unnecessarily triggering garbage collection), you should be fine.
So I will leave it at that for today. I hope I’d managed to outline my problems regarding programming today for you. I will go into more detail about how we at 2GuyGames go about improving readability, changeability and maintainability another day. Next time Stefan will be back with “human resources”. Grab yo’ pickaxe, we are going to mine some humans from the blockchain. But what are we going to do with them? We will find out in two weeks!