Refactoring and Mad Ramblings
Moving one step forward and two steps back, I decided that I needed to create a fancy, new system for rendering simple primitives. I had an existing one in my engine, but it was written a few years ago and I was finding that the capabilities it offered were now inadequate and didn't sufficiently take advantage of the new stuff I now knew how to do (like hardware instancing using HLSL). My dream was to create a super powerful, robust, one stop shop type system for doing all types of primitive rendering using hardware instancing. You'd be able to render point sprites, quads, billboards, lines, textured and untextured triangles, etc. using one system for it all. This "primitive system" could be extended by a particle system as well: The particle system would pretty much be responsible for telling the primitive system when, where and how to render a primitive and the primitive system would take care of everything else and render it using hardware. The only bottleneck would be the GPU, and going by the advancement of modern hardware, it's quite a fat pipe to throw triangles around in before performance becomes an issue.
Anyways, that was my half step forward. I started implementing it, and as is typical to true programmer fashion, I found so much "stuff" that needed to be fixed/reworked before I could go forward. I decided to reorganize my game engine by sorting classes and name spaces into a more logical manner. For example, I have this static "Calc" class which has a buttload of handy math functions which was stored in a generic "Utilities" namespace. I also had an XML parser stored in there. "Wait a minute, that makes some sense but not enough sense!" I said to myself... "The calc class does math, so I should create a "Math" namespace for it!" and "XML has to do with reading files, so it should go into an IO namespace!". A "utilities" namespace is too vague and smells like a trap which can collect too much garbage if I'm undisciplined.
I know I'm getting into irrelevant minutia here, but it just goes to show how far into the weeds I'm going with this refactoring effort. The reorganization makes a lot more sense and leads to more clarity. Clarity is good, even if it takes a step back to gain it. My usual programming methodology is something along the lines of "Just get it working, get it done, doesn't matter how or if its ugly -- figure out how to make it pretty later!". As an agile practice, it's alright... but as I'm seeing now, if I take any sort of sloppy approach, it just means I'm going to have to go back and rethink & rework that area of code at a later time. I think its unavoidable though. When you're taking a first stab at something, you barely know what you want or need so you can't expect yourself to get it perfectly right the first time. If you aim for perfection the first time, you're going to take too long and you'll probably over engineer parts which end up unused. Hence, Lazy + sloppy design + refactoring = more efficient?
Anyways, this primitives system is going to be a large backbone in my game and game engine, so it's worth it to put in just the right amount of effort to make sure its done right. And to do it right, I have to make sure the framework its relying on is up to snuff. At the end of the effort though, you really have to take a step back and honestly ask yourself: "What did your game gain from this effort?" and if you don't have a good answer, maybe it was a waste of time and effort which could have been used more wisely elsewhere. That's a harder call to make when you're working on more abstract, intangible bits, right? The trap you want to avoid is fixing things which aren't broken or over engineering things beyond whats necessary.
Oh yeah, when I decided to reorganize, decouple, and rearchitect everything, I also didn't make any backups of my working game (probably not wise). It certainly doesn't compile right now and it's got a few dozen errors right now. It's also required me to revisit previously working classes and update them to the new architecture, possibly breaking them completely. I wildly estimate I have about 150k-200k lines of code and have exactly 170 classes. I have every confidence that I can get my game to compile and run correctly, but its going to take a lot of time and effort on my part. The game will only grow in size (probably quadruple the class count?) so it's super important to have everything well organized before it grows any further.
I recently got interested in watching Chef Gordon Ramseys "Kitchen Nightmares" television show on netflix. The gist of the show is that he goes to visit failing restaurants and tries to help them get back on their feet before they have to close their doors. Surprisingly, I find that this show is less about kitchen problems and more about the people problems in and around the kitchens. He'll walk into a kitchen and it is filthy. The cooks are arrogant or incompetent. There is no leadership. No organization. It's pure chaos and confusion, everywhere, every day. The nightmarish kitchen is just a manifestation of these people problems. The core tenants Chef Ramsey adheres to seem to follow this theme: "Simple menus. Clean kitchens. Fresh, quality food. Good cooks. Good communication. All brings good food and happy customers."
I feel a lot of those same principles can be applied to making a game: "Simple code. Clean code. Commented and documented code. Good programming discipline. Good consistency. Good design, good vision. All brings good games and happy players."
You don't want to have a nightmare game project, so when things get dirty and out of control, it's time to roll up your sleeves and start scrubbing that dirt out. Coding further is like cooking in a filthy kitchen: Whatever you create will be contaminated and unsanitary until the underlying problems are resolved.
Heh, one advantage of working alone is that I don't have to hold clarification meetings or try to sell other people on my ideas. On the other hand, if I'm about to shoot myself in the foot, nobody is there to stop me... It's a true test of competence and capability.
Enough rambling! Back to code and coffee!