This is a topic I feel strongly about, but at the same time I am very aware that its very difficult to get across in text, because its not something you can really illustrate with a single line of code, or a witty cartoon or a small diagram, so I may go on a bit here…

I have been looking at code *not written by me*, and also talking to friends learning some new stuff who are also working with other peoples code, and have been reading a book on this topic, so my head is full of opinions on the topic of coding versus software engineering. let me first explain the difference.

‘Coding’ is the skill of understanding syntax and principles of how programming works, and slapping together a bunch of code that makes something happen. This is not *that hard*, and in fact yes, you can buy totally serious books that claim to teach you C or C++ in 21 days or less, which is laughable…but yes it does allow you to write code that compiles without errors and does the thing you want it to do.

‘Software Engineering’ is like coding, but much much HARDER. Mostly its about the scalability and long term usability of what you code. Code may ‘work’ in the same way that replacing a key component of an old car with a coat-hanger or a piece of string may *work*, but its likely going to go wrong at some point, nobody else will understand what it is or how it works, and when you try to scale it up, everything may completely fall to bits.

Software engineering is a pain because the best way to really get good at it is probably just experience of writing very large programs again and again and again, with different people, on different platforms, with different requirements, and having people criticize your code, or finding bugs in it, or having to revisit it five or ten years later to fix stuff.

The problem is that to 99% of people, and even 95% of coders, the difference between coding and software engineering is actually REALLY hard to spot. because many coders are managed (especially in the games industry) by non-coders, they aren’t even encouraged to get good at software engineering, because frankly the boss doesn’t know what it is.

When you are working as a coder, in crunch, at a game studio with deadlines, generally speaking the boss wants result X by date Y. The big problem is that result X is really shoddily defined. If ‘compiles and runs and the QA team couldn’t make it crash’ is the criteria, then LOL, yeah done easily mate. Unfortunately anything beyond that level of skill goes unrewarded, because its REALLY hard to spot.

Luckily I’ve worked for some very clever coders. My first coding boss (at elixir) was Dave Silver, who is now a mega-celeb in the world of AI at DeepMind. My second coding boss was James Brown (Lionhead), who now spends his time replicating conways game of life using lego for some reason. Both of them were very clever, and I’m a better coder for working under them. I learned a lot from them, not about *code* (which you can get from a book) but about software engineering.

If you haven’t already read ‘Code Complete‘ I really recommend that you do. Its excellent and is probably step one on the path to this stuff. The next things you should do are to work on a BIG project with other coders, and also work on the complete ‘project lifecycle’. This means, you start off with nothing, and finish when the project has shipped, and gone through multiple updates, ports and patches. Only then do you really know if the architecture choices you made at the start are correct.

A fairly simple blog-post style tip on this stuff concerns feature/syntax use and what I call the ‘gunslinger’ attitude. Take this line of C++:

X = X +1

Pretty much anyone (coder or not) can tell you that this adds 1 to the value of X. You can also write this

X += 1

Which does the same thing actually, and theoretically is very very very slightly faster because X is only evaluated once. However, its dark times indeed if in 2020 we cant expect a compiler to realize this and do that sort of thing for us.. Lets get a bit more vague…

float fInitA = InitA > 0 ? ( float )InitA : 1.f;

WTF? Now I am a C++ coder, so I can understand this… but I have to actually engage my brain to do so, which slows me down. Its not immediately intuitive to my half-asleep brain exactly whats going on here and… It really does not have to be written this way. You can just do this:

float fInitA = (float)InitA;
if(InitA < 0)
{
  fInitA = 1.f;
}

And OH MY GOD THE HORROR, its 5 lines of code instead of one. My god. What a n00b. Obviously this idiot doesn’t know about the C++ ternary operator and its syntax. The fool!

And yet its actually readable, and much easier to debug because its multiple lines allowing for breakpoints. The longer simpler version here is much BETTER code. And thats generally IMHO a principle that you can stick with. The trouble is, some coders adopt a ‘gunslinger’ attitude where they are presumably living out dreams of alpha-male dominance through writing the most complex obfuscated mess imaginable. Believe it or not your job as a coder is to write CLEAR and MAINTAINABLE code. You do not get fined for every line you use, and you do not earn points for confusing the people working with you.

There is a very ‘macho’ culture in programming, built around showing off, and using obscure stuff that you just learned. This is nuts. Just because you learn how to use a certain feature/function/syntax does not mean you HAVE to use it everywhere. I’ve worked with coders like this. Its a nightmare.

Its a worthy goal to write code that someone who isn’t even a programmer can look at and go “errr… I think I can see what you are doing here.”. This is because really GOOD code is code that can be understood by someone you have never met, five years later when a bug has been found and they need to work out if its in that function or not. If you are writing a tiny program thats only 1,000 lines of code and nobody else will ever see it, and you will never edit it then…ok maybe you can hack it together, but a proper software engineer always writes code that can be maintained.

Programming is a HUGE topic, and to get good at it, to get REALLY good at it takes an entire lifetime. I started coding aged 11, which is 39 years ago. I think I’m pretty good at C++ now, but not an expert, and its the only language I’m comfortable with. The internet and its many youtube vids and forums have spawned an attitude that you can learn to code one summer, or during lockdown, and…yeah not really. You can learn to hack stuff together by copying and pasting from stackoverflow…but thats really not proper software engineering.

Its worth saying I’m not exactly at the end of the journey myself yet either. The code for Democracy 4 is *not perfect* by any means. Some bits are hacky, there were some fundamental design decisions I made about 15 years ago with the basis of my GUI library that are embarrassing but still there (of COURSE buttons should be a subclass of window you idiot!), but overall my code gets better with each game.

I coded about 5 games before I realized that having a decent separation and naming convention to keep GUI and Simulation code entirely separate was a worthy thing! I probably coded 8 games before I had a rock-solid translation-management system that meant not a single line of text exists in code. It took me maybe 10 games to get threading to work safely, and maybe another 2 until I had a rock-solid and highly-optimized multi-threading system. I didn’t really start to use the power of macros for about 10 games. I’ve only just (in the last 2 games) really got my code for setting up configurable color palates to be usable.

I had most of the technical knowledge to do all of that stuff about 15 years ago, but to do it *well* and to know how to arrange things, and to set them up to be re-usable, optimized, stable, and readable… thats what those extra fifteen years were spent doing.

The VAST majority of comments you read online about programming, especially games programming are written by coders, not software engineers. They suffer a lot from the delusion that they have mastered code, because (as is natural) they don’t know what they don’t know. Its REALLY hard from a distance to spot the software engineers from the coders, but in my experience the amount of time they have been in the industry, and the number of large completed projects is a really good sign.

A final way of spotting the difference: If a lot of someones code has been copied and pasted from stackoverflow or pastebin then… yeah. Thats not a software engineer.

12 Responses to “Coding vs Software Engineering”

  1. Jo says:

    I like Casey Muratori’s style, where he makes things as simple as possible. His APIs appear to grow and shape themselves like magic. He also mocks those who make the simple complicated. Unfortunantely it looks like he is fighting a losing war, and a lot of software companies are going to fall, because of the clever fools infesting the industry. On the bright side, perhaps a big collapse will leave room for better companies. I really hope so.

    Programming has never seemed that hard to me, unless you are going to the metal with assembler. The real challenge is math. If you aren’t a great mathematician, you can never be a great programmer.

    The irony about the very top level of programming in games, is you must have the IQ of an astronaught, so you can sit in a cubicle for 60 hours a week, churning out games aimed at the dumbest people on the planet. I don’t care what anyone says, running down corridors shooting at cookie cutter monsters would not challenge an astronaught’s brain in the least.

  2. Sam says:

    One thing I like about some of the more recent generation of programming languages is a recognition of this. A large majority of the people writing code will not be experienced enough to tell when they’re shooting themselves, their colleagues or their future selves in the feet. Therefore, a language that to the maximum extent possible prevents people doing that is a good idea. I think also a recognition that the culture of the language contributes to this matters. C++, for all its power, lends itself both in language design and culture to writing unreadable code and solving every problem with the cool new feature you just learnt. I’m a big fan of Python’s “Zen of Python” – “Explicit is better than implicit. Simple is better than complex. Readability counts.” and so forth. Likewise Go’s simplicity, readability, and multiprocessing-focused design. More modern languages also tend to have testing tools as a first-class language feature.

    You obviously can’t trick people into getting large-scale software engineering right solely through language design, but you can certainly address a lot of the building blocks and let people focus on learning the hard bit!

  3. Guntha says:

    I can’t count how many jobs I interviewed where I was asked coding questions about how inheritance and “virtual” behave in C++, and I never got everything right. If you’re using tools so confusing that you think they would make good trap questions in an interview, maybe question your tools?

  4. Alex says:

    Your two examples of clamping the value of a float actually handle 0 differently. Much better than either from a readability and maintainability perspective would be to extract the logic out to a function whose name concisely describes what it does and call that where needed.

    • notethecode says:

      > extract the logic out to a function

      Personally I wouldn’t extract a four-line snippet into a method, very short methods like this aren’t worth it. It might just take slightly less lines on-screen, but when reading the code, you have either to read the function name, then understand/remember what it’s supposed to do or go to the definition to read, then go back to where you come from, whereas just the four lines can be read and understood at a glance.

      • Trevor Tiernan says:

        That’s why you need a universal, simple, and single minded way. For instance this both casts and sets a minimum value. This is 2 things instead of 1. Now if there’s a universal term . Let’s say “clamp” then we could have a method (better yet an extension)
        float fInitA = InitA.ClampTo(1)

  5. Gabriel says:

    Sorry for posting this here, I couldn’t find your email

    Your rss feed appears to have broken down during the weekend, and is returning garbage

    • cliffski says:

      Yup, the whole RSS thing is seemingly broken, so I removed it :(

      • Trevor Tiernan says:

        mobile_index.html is also broken. I think it’s because it’s using http instead of https.
        On iPhone’s safari I’m not able to get to the blog through the link. Gotta go direct. :(

  6. Amir Barak says:

    I’ve rarely met a modern C++ program that does in 5 lines of code what could be done in 57 and 12 template variations..

    • Cool McCool says:

      @Amir Barak
      That’s because C++ is C with many extra features for no extra benefit.

      @OP

      Beautiful!

      DISTANCE getDistance(OBJECT *from, OBJECT *to)
      {
      return !validObject(to) ? distUnknownObject :
      to == from ? distSelf :
      to->location == from ? distHeld :
      !isLit(from->location) &&
      !isLit(to) && !isLit(to->prospect) ? distNotHere :
      to == from->location ? distLocation :
      to->location == from->location ? distHere :
      getPassage(from->location, to) != NULL ? distOverthere :
      !validObject(to->location) ? distNotHere :
      to->location->location == from ? distHeldContained :
      to->location->location == from->location ? distHereContained :
      distNotHere;
      }