So the Discourse has tacked once again to, "is Good Code needed for Good Games"? This time, a page of Balatro's source code made it to Twitter and some people laughed and laughed at the if-else chain and some people were like BALATRO SOLD A LOT THEREFORE EVERYTHING IT DID MUST BE THE CORRECT WAY
But there are points for and against Good Code. Good Code is a land of contrasts. First of all, what do you mean by Good Code?
(Note in case it wasn't obvious: When I say Bad Code and Good Code, in both cases, I mean code that works. If you're writing code that doesn't work at all, refer to Knuth or something.)
- Pretty Code: "It has sensible and consistent names for functions and variables. It’s concise. It doesn’t do anything obviously stupid. It was written by a single person, and never touched by another. It reads like poetry written by someone over thirty." This is a standard if-else chains immediately fail as they inevitably look like a first-grader's effort.
- Performant Code: This is the code that goes fast. A bit outdated since computers became able to do more than one operation per second, but with an unexpected comeback in Zachtronics games. Expect opcode count and loop unrolling to be mentioned.
- Enterprise Code: This is code designed to be passed around. Enterprise code will go through dozens of programmers, few of which know each other and none of which talk to each other. Each of them sees the code through a toilet tube, and expects to make changes in their section that won't set the whole project on fire. At this level it's fully acceptable to have the same function copied across three different libraries, each with slightly different side effects, because the alternative is worse.
- Maintainable Code: Code that makes bug-squashing and extending easy. Sensible naming is just the start. If you want to add a new element to the game, how many files do you need to change? Do you even know the names of all of them?
A good way to cause arguments with other programmers is to choose one of these as Good Code to the neglect of all else.
Next, if i remember, i'll get to the actual subject of this article - when it's the case that you shouldn't do any of these things (and the terrible implications thereof). Stay tuned.
So, having seen all the wonderful advantages writing Good Code can bring you, why would you ever write Bad Code?
- You're prioritizing some other form of Good Code. Coworkers picked on me a couple of times for making method names that were over 60 characters long, which I did when the method was a one-off and should absolutely not be reused elsewhere. Similarly, another coworker insisted on passing object ids as untyped integers for efficiency, which was an absolute joy when it came to debug a function taking in four of them at once.
- You're constrained by the system. Maybe your code is in Lua, which thinks having a nice enumeration is for little babies. Maybe your language has no IDE with an autocomplete worth a damn and maybe you don't want to type 20-character variable names every time. Maybe your senior programmer has decided that Systems Hungarian Notation is the one true naming scheme. Maybe the Man won't let you chain ternary operators in order to fit your entire on one screen, because "it's not company policy to make debuggers want to commit suicide". Compromises are made.
- You don't know how. Programmers constantly want to do novel things, yet will often refuse to admit they're learning as they code. A programmer will often run into a situation where they don't know how to implement something, let alone how to implement it cleanly.
- You're in a hurry. Clean, maintainable code takes longer to write than just using the first thing that pops up in your head. If you have to do a hundred tasks by tomorrow or the game won't come out, doing the code equivalent of running a big extension cord through the middle of your living room starts to sound very reasonable.
- It's not important. You're not particularly in a hurry, but you do have better things to do with your time. Such as, for example, anything else in life other than tidying up a if-else chain that is called maybe once per frame.
Maybe this whole thread should have been called "When to write Bad Code". anyway, next should be, finally, why Bad Code is Bad.
Nourished by the defense of bad code.
I write bad code. I did not write a single function for my first game, which took over 4 years to make. I did not know how to do very much beyond if/else stacks. (The game now includes 3 functions, which I wrote for a major update.)
Did it take so long to make because I couldn’t code? Surely that’s a factor. I wasted plenty of time pasting the same code all over the place. It took a hell of a long time to debug. Was it in the cards for me to learn code outside of game dev hours? Definitely not. The only way to finish was to press forward.
I coded the game while pregnant, my time ticking away before my next life began. I coded the game while breastfeeding. For many months I’d get 2 hours a day to work, if nothing went wrong. Eventually that was maxed out to 4. Yes, I’m painting the best “make up a guy and advocate for him” picture I can. But there’s no version of my first game that wasn’t coded under duress with very little knowledge. I imagine that’s the case for a lot of games we like, with better and worse code than my own.
I think people should be happy to know how flimsily a popular, beloved game is held together. It means any of us could manage it. Where I come from in cartooning, we don’t care how good the pencil stage looks, unless we’re little freaks who dig our own process way too much. The rest of us are finishing books.