Hmm, from what I can tell, Minecraft is fairly successful, despite it being a "perfect example" of not having enough abstraction.
Of course, you fail to really acknowledge the risks of premature abstraction. Sure, if you could see the future, and know what patterns could be usefully factored out into abstractions, it would be good to start with those abstractions. But what happens if you incorrectly predict that an abstraction will be needed? You create a bunch of unnecessary framework code that is harder to understand, likely less efficient, and worst of all, you wasted time writing code that you didn't need.
YAGNI is not a cop-out. The best way to create abstractions is from concrete examples. Write something once. Then, once you actually find yourself writing it twice, abstract it out. That guarantees that you don't waste time on things that you don't use. It also generally leads to better abstractions, because you have concrete use-cases to work from.
Anyway, back to the Minecraft story, who are you to say that the game would be better if Notch followed the premature abstraction strategy? Isn't it possible, perhaps, that he would have wasted enough time implementing ivory towers of abstraction that he might have left out the features that actually made the game fun?
But what happens if you incorrectly predict that an abstraction will be needed?
Then you made a mistake and hopefully learned something. I didn't say architecting software was easy or without risk, just that you can't avoid doing it by following simplistic rules.
The best way to create abstractions is from concrete examples. Write something once. Then, once you actually find yourself writing it twice, abstract it out.
It's nice when things go that way, but it's not the general case. Often, by the time there is a concrete use for abstraction, the damage is done. For example, adding network multiplayer to a game that has been architected for single player is a nightmare of hacks and duplicated code (Notch has explicitly lamented about that one).
Anyway, back to the Minecraft story, who are you to say that the game would be better if Notch followed the premature abstraction strategy?
Notch himself seems to be saying as much in that blog post. But that aside, I'm a fellow game developer who has spent dozens of hours reading and modifying the Minecraft code. Even after a round-trip of obfuscation, it tells the story of its creation quite vividly, and the theme of the story is "hack around it!" Though I still have tremendous admiration for the game and its developers.
I think the point was that the source code doesn't make the game better or worse.
A nightmare of hacks is fine as long as the product is great.
IMO writing such code is sometimes even better, especially for a solo developer. If you aim to write beautiful code, it might eventually outweigh everything else, while giving a false impression that you're doing the right thing. Your goal is the product, not code. I'd argue that you can't focus on both (it's called ‘focus’ for a reason).
Of course source code makes the game better or worse. The game is made of code. The code makes the game what it is.
If you write good code, your product will work better and be done sooner. This is the definition of good code. If you write bad code, your product may be overbudget, buggy, inadequate, and so on. This is the definition of bad code.
There is no dichotomy between the product and the code. To suggest that you can make better software by neglecting the code is absurd.
No arguing with that. Same as building material makes a house what it is. The question is, does the success depend on material used? You can build a great house amidst the desert.
But that's an analogy. More real-world example—imagine two startups:
- Startup 1: bad programmer, good QA.
- Startup 2: good programmer, bad QA.
Where would you invest your money?
> If you write bad code, your product may be overbudget, buggy, inadequate, and so on.
Here I disagree. Overbudget? It depends on product success. Buggy? If you have good QA, it's not buggy. Inadequate? You can write the cleanest code, but your product won't work as users want it to.
When we say ‘great product’, do we mean that it has nice clean code, or it's something else? How many great products have bad code?
> There is no dichotomy between the product and the code.
As long as you are ‘just a’ developer, and there are other people focusing on product and its functional quality. In that case you receive specific tasks with deadlines, and yes, you should focus on writing good code.
Not so if you're a solo developer.
1) No one will focus on the product, except you.
2) You most likely would be heavily biased towards writing good code. (Because you're a developer, you're supposed to write good code, right?)
You need to force yourself to focus on the product, to avoid becoming the Startup 2 from above example. Intentionally writing bad code is one way to do that. In that case you at least can be that Startup 1—you'll be forced to pay more attention to functional quality (as opposed to structural), so you'll be good QA.
You can argue that one can focus on both. My opinion is that it's too risky. You need to have priorities set as clear as possible.
> To suggest that you can make better software by neglecting the code is absurd.
Yes, it sounds really controversial (especially to a programmer). I'm far from satisfied with that statement. What would be a better way to be a good QA while being a great programmer?
Multiplayer mode can be extremely hard and can take any fun out of being an indie game developer. I'm still not sure if it is the right abstraction to work in on day one.
Of course, you fail to really acknowledge the risks of premature abstraction. Sure, if you could see the future, and know what patterns could be usefully factored out into abstractions, it would be good to start with those abstractions. But what happens if you incorrectly predict that an abstraction will be needed? You create a bunch of unnecessary framework code that is harder to understand, likely less efficient, and worst of all, you wasted time writing code that you didn't need.
YAGNI is not a cop-out. The best way to create abstractions is from concrete examples. Write something once. Then, once you actually find yourself writing it twice, abstract it out. That guarantees that you don't waste time on things that you don't use. It also generally leads to better abstractions, because you have concrete use-cases to work from.
Anyway, back to the Minecraft story, who are you to say that the game would be better if Notch followed the premature abstraction strategy? Isn't it possible, perhaps, that he would have wasted enough time implementing ivory towers of abstraction that he might have left out the features that actually made the game fun?