35 comments

[ 4.2 ms ] story [ 63.1 ms ] thread
Posted this because I remember seeing it a few years back and was like 'woah, thsi is bad.'
Why is it bad? It fulfilled all purposes: It made the developer some (a lot of?) money, a bunch of people very happy, Terraria shares among the most positive reviews of all games on steam (also meaning there can't be too many critical bugs, as that would piss off gamers pretty easily), was/is frequently updated since years, and is generally considered "a good game".

What would a metric such as "clean code score" help with any of this?

The code looks bad. I guess it has been refactored later.

The repo says this code is only for educational purposes. This spaghetti can be still a good example for the reasons you mentioned. Or maybe it is a good example for an ugly prototype version of an game.

This could be even better if people could see a refactored version of this codebase.

This 100%. You are doing a great job if you maintain clean code for 50% of the project, because that last 50% will be a mad dash to get to ship.

Source: 12 years in gamedev ;P

Games don't optimise for "clean code" or maintainability - they optimise for speed and cost. Of course in a perfect world it would be all of those.

- Former game developer

I'm really wondering why clean code or maintainability imply higher cost or lower performance for you.
Because game code is "throw away" = don't assume you are making a sequel = there's no reason to make it maintainable. You write it as fast as you can to fulfil the requirements. Stuff like unit/system tests are a waste of time because it's cheaper to hire people to manually press buttons.

Yes I know this sounds bad - but that's how the games industry works. And is one of the reasons I left.

Note that if you are working in engine code, then you want all the automated tests, proper architecture, etc.

It's pretty clearly reverse engineered from bytecode by some sort of tool. It's full of `goto IL_label` statements. Would a programmer write a goto in C# at all, let alone call their procedures "intermediate language xyz"?

  if (num9 + num7 >= num6)
  {
    num8++;
    num7 += num9 - num6;
This looks a lot like decompiler output.
It is. The author of the repo wrote about it here in German: https://thevamp.cc/2013/10/12/terraria-1-2-decompiling-und-s...

From what I can tell this was originally motivated by bugs in the German version of the game. Back then 1.1.2 was to be the last version of Terraria (a running joke at this point, they announced 1.4.4 a little while ago) and so decompiling seemed like the best option to get those bugs fixed. This might be a more interesting blog post on that topic: https://thevamp.cc/2012/07/16/terraria-1-1-2-zu-terraria-1-1...

this looks like a decompiler's take on the "why was 6 afraid of 7" joke.

it would seem decompilers are not that funny.

100% this is decompiled output. There's no way this would be a single file. There's no way there'd be `String.concat(new object[] { "Some", '\t', "strings" })` written by a real human. This is reversed from some bytecode and the decompiler had to make some guesses as to what the original code was.

Don't judge the developers based off of this.

> Don't judge the developers based off of this.

I'd go further and say "never judge a developer by the code they write without knowing 100% of the context". So many times developers trash each other for shitty code quality without knowing anything about why the code was written the way it was. There isn't always good reasons for "excellent code", sometimes good enough is perfect. We like to think we all live in a vacuum where there is no reason for code to not be perfect, but we forget we live in an environment which is not perfect, and the code is meant to contribute to the this environment, sometimes leading to less-than-perfect code.

So before you judge your fellow developer based on code, ask them first to explain the context around the code, before jumping to any conclusions.

> we live in an environment which is not perfect, and the code is meant to contribute to the this environment

That's a really delightful take! Makes me feel like the code I throw at the wall to see what sticks does make a difference in my corner of the world.

When you add that the definition of perfect can be subjective, one person's definition of perfect might have evolved into it by passing through what is now their good enough definition.

Amen. Even the best coder can write trainwrecks if given sufficiently little time and subject to enough pressure.
So many times developers trash each other for shitty code quality without knowing anything about why the code was written the way it was.

In a perfect world, that context would go right into comments next to the code.

In a perfect world, we'd have no problems and hence wouldn't need code in the first place ;)
The chains of else { if(...) { ... } } are unmistakable. I'm surprised the decompiler couldn't figure out the else if, honestly.
This version is more up-to-date and has a readme: https://github.com/UTINKA/Terraria

Having looked at a few games' source code, are there really any complex games with pretty code? With as many subsystems, items, and enemies as Terraria has, it feels almost inevitable that you'll have complexity like this snippet for determining when to spawn the hair stylist NPC:

  else if ((int) Main.tile[index1, y].wall == SpiderUnsafe | flag10)
  {
    if ((int) Main.tile[index1, y].wall == SpiderUnsafe && Main.rand.Next(8) == 0 && (!flag6 && (double) y >= Main.rockLayer) && (y < Main.maxTilesY - 210 && !NPC.savedStylist && !NPC.AnyNPCs(WebbedStylist)))
    NPC.NewNPC(index1 \* 16 + 8, y \* 16, WebbedStylist, 0, 0.0f, 0.0f, 0.0f, 0.0f, (int) byte.MaxValue);
  else if (Main.hardMode)
    NPC.NewNPC(index1 \* 16 + 8, y \* 16, BlackRecluse, 0, 0.0f, 0.0f, 0.0f, 0.0f, (int) byte.MaxValue);
  else
    NPC.NewNPC(index1 \* 16 + 8, y \* 16, WallCreeper, 0, 0.0f, 0.0f, 0.0f, 0.0f, (int) byte.MaxValue);
  }
>Having looked at a few games' source code, are there really any complex games with pretty code?

Games don't have the same maintenance requirements as a web application. They are made, shipped, played, and forgotten. So code cleanliness is generally an afterthought. And honestly, most indie game developers are not great programmers. But making a great game has very little to do with programming nowadays. The tooling has come so far that many hit indie games are now built using "no-code" solutions like Unreal Blueprints. And advertising that you hand coded the entire game in C with immaculate coding standards wont make it any more fun.

> They are made, shipped, played, and forgotten.

Terraria was released in 2011 and is still getting updates.

(comment deleted)
>Terraria was released in 2011 and is still getting updates.

Yes, it was a runaway success. Terraria is a huge outlier in the indie scene for lasting so long. But my point is that the creator almost certainly was not planning to be maintaining this code 10 years later when he wrote it. And so it was written for speed and simplicity, not elegance and maintainability.

(comment deleted)
Games are being updated for a lot longer these days.
> Having looked at a few games' source code, are there really any complex games with pretty code?

I haven't seen the Factorio source code, but having read their blog enough, I have to believe they have beautiful source code.

I would recommend anyone in IT to read their blog (and play the game a little for the context) to understand how to wisely deal with complex systems and learn good programming practices.

https://www.factorio.com/blog/

Since this is decompiled, you really can't infer much from it, in terms of code quality. The original might have really detailed comments, and involve additional functions that have been inlined.
If it's decompiled, then it seems like the decompiled output is a derived work from the binary. And to distribute that derived work on github with a license "Only for educational use" seems like it's infringing. GH should probably take it down.
The Terraria devs don't care and actively encourage modding. Otherwise they'd have used an obfuscator.