He uses poor OpenGL practices, and sees poor performance as a result. He also designed the entire product in a way that makes it cumbersome to mod, without a consistent interface or a logical way for mods to work together. Modding Minecraft as a whole is one big hack.
I'm more familiar with the networking side of things. The Minecraft networking protocol is a mess. There are 9 or 10 different ways to encode a vector in the protocol. He made up "Named Binary Tags", a dictionary serialization format, which could have better been served with existing tech. He frequently misuses signedness in the protocol. He made up another obtuse dictionary format for describing entity metadata. He screwed up backwards compatibility for the only thing that needed to be backwards compatible - three times. His colleagues later screwed things up even more.
Also network programming and game/graphics programming are different disciplines with their own challenges. Big studios might assign different people to these tasks, so I wouldn't expect somebody to be amazing at both.
He came around to it, though. By the time he handed Minecraft off he was fully in the “modding is great for Minecraft” camp. But the game was never developed for that. A real modding API has been in the works for quite some time now, but it seems to be quite hard to pull that off.
It's not written to be "modified". It's not written with a specific modular outcome in mind. It's more often than not a one-off messy code that gets the job done, because that's the requirements and the pace of the industry.
And, especially for something like Minecraft, it has to be original and even explore the problem space and ideas in the process of building it. It's not something you do based on a design carved in stone, with some cushy strict waterfall method or what have you.
Building games, and especially such games, is an explorative process, and one-off process, and a war on many fronts (e.g with time, or with tons of competing gameplay ideas).
You are only able to say what you say, because you look at the code in hindsight.
You can adopt some good coding practices that ensure that the code isn't a spaghetti mess that's hard to understand when you come back and look at it. That's different than designing a system to be pluggable from the start.
So, I haven't watched any of Notch's livecoding videos, but for those who have, what kind of bad is the code? Is it bad "this is a mess and I won't remember what these variables do in 3 months" or is it just simply designed to handle the most immediate case (coded well but not with plugins in mind)?
This is when you refactor. It's that moment of realization when coding and you say to yourself "ah, if I had a compositional object model instead of a god object inheritance nightmare I could introduce new objects so much faster and without destroying the interface of CEntity."
You quickly also realize this means re-writing your inheritance tree, decomposing all of your object classes and reconstructing each one as a bundle of components like renderable, effects, behavior, physical (position), that communicate and interact through messages.
You finally have the flexible buildable adaptable object system to meet your building and maintenance needs. But you had to rewrite 30 classes to get there.
My take is badasses in that moment take the 20 hours and do it right. Many like Notch simply didn't bother. Everyone pays for it later.
"But it's not necessary" they say. What's necessary about being great? Nothing, but being great is Awesome. That said, one would need that attitude to bite into 20 hours of extra unnecessary work with a smile. But it's the starting recipe for a great programmer.
Not really. It's rather pointless, time consuming, and often deleterious to one's work/life balance. Not to mention it can mean that the end result might never ship at all, in an endless pursuit of "greatness".
Being great is overcoming the reasons you are giving not to do it. Being great is having the vision to see how these decisiosn impacts your ability to deliver in the future.
Being great isn't necessary. And you've pointed that out. Your attitude ensures that the code you write meets your standards. Your standards, aren't "great."
Maybe Notch didn't start building it with the idea that anyone would want to mod it. Heck, maybe he didn't even anticipate that it would be popular enough to require great performance. If he expected the game to be played primarily by him and a few friends then he could forego performance for beefier machines.
If he started out trying to build a game that would need to be extremely easy to mod and be performant on millions of machines of varying performance capabilities, he probably wouldn't have gotten around to actually writing it in the first place. It's called over-engineering, and it kills more projects than anything else, IMO.
-Don't make up things where existing tech would do (ala NBT, entity metadata, etc)
-Don't use a signed number if negative values don't make sense in that context
-Include versioning if something needs to work across versions
-Choose consistent scemantics for data encoding (and anything else you can)
All of this will make it easier for you, too. Focus on reducing internal code reuse, maximizing external code reuse, and simplifying things.