By PeezMachine 6 Comments
Having been awake for 24 hours, I was slumped over in a chair in a physical therapy office's waiting room while my friend was doing some work to recover from ACL surgery. The previous night, if it could be called that, was supposed to end at a somewhat reasonable 1 AM. I had finished setting up the file and asset structures for SummerJammers and decided to do a quick debug run to make sure that everything was in place and that all of the new code was working as expected. And it was, for the most part, save for a funky little bug where the PlayerAvatar object was receiving Draw calls but not Update calls. I traced the issue to a known issue with how I was implementing SortedSets, namely that a DrawableGameComponent (formerly known as SuperDrawableComponent before I just decided to hide the existing XNA.GameComponent classes) would always try to compare itself to other components using its DrawOrder even when it was supposed to be comparing by UpdateOrder. So I took a few minutes and thought about polymorphism and blah blah blah and decided that it could wait for tomorrow, seeing as how I had an early morning of driving my buddy to PT.
But Blizzard works in mysterious ways, and one email check, one Hearthstone invite, and six hours of digital card-slinging later, I'm there in that waiting room feeling strangely alert despite the protestations of my eyelids. I had forgotten to bring a book to read, so instead I thought about my tumultuous month-long history with XNA's GameComponent class. I had written, deleted, and re-written a lot of code to get the functionality I needed out the GameComponents while still using as much of the existing XNA library as possible, and before the previous night's Hearthstone binge, I had closed up my work with a nagging feeling that I was on the wrong track a bit, that I was going in circles and that my issues with the SortedSet were just symptomatic of a problem that Microsoft had been smart enough to forsee – hence their particular GameComponent implementation and the design of the GameComponentCollection class.
But there, as The Sitting Dead in the waiting room, it hit me. I understood how the XNA GameComponent architecture worked and how it was incompatible with my needs. I understood how a lot of the code I was writing was adding funcionality that already existed in XNA for its GameComponents that wouldn't work for my implementation. After a month of chasing my tail and second-guessing myself about this most fundamental part of the game engine, I understood how my implementation – which greatly streamlines the process for dealing with GameComponent update and draw orders – is in fact a nearly ideal way to get around the many different constraints not just from the XNA library, but from the principles of good object oriented programming. I laughed a bit when I realized that in a month of work I had essentially just re-written a couple of out-of-the-box XNA features, but it was necessary in order to build the engine I wanted. And after all, how much can you really know about something until you take it apart and rebuild it?
So yeah, it's been a good week for SummerJammers. The component classes are complete and locked down, and I replaced the SortedSets with standard Lists and a custom sorting method to fix that issue. In more exciting news, I created all of the code that outlines how assets are loaded from files and used within the game. It's a system that ensures that assets are only loaded once (all praise be to sprite atlases!), can be shared between all game objects, and can be loaded either as-needed or at predefined moments. You have no idea how exciting it is to look at a file structure in code and say “holy shit, these are the sounds and images that are used in the game.” That's not to say it's a hard thing to do. In fact, doing the asset and file structure work has been the easiset part so far. And that was the problem. I had so many possible ways to do the file structure that I ended up writing and re-writing it three or four times trying to make it perfect. I've been bugging my talented and brilliant buddy Adrian for the duration of this project about big-time computer science questions, but I think the biggest help he's been so far has been when he just said “no one file structure implementation will solve every problem, so just pick one that works for you.” If not for that, I'd probably still be looking for a file system unicorn.
On a side note, let me just say that it's been a TON of fun getting an excuse to think more and more and more about the inner workings of computers. Sure, I've been tinkering with computers since I was in elementary school and took classes in computer science digital engineering in college, but it's nice to just have a new excuse every day to jump down another rabbit hole and learn about something in more depth or start making new connections between ideas. For example, writing the asset system got me thinking about the functional difference between the image file on your hard drive and a code object that your game keeps in memory for internal use. It's something I had thought about before, but working on SummerJammers has given me a reason to appreciate it.
So that's that. Basic engine stuff is done. The parent/child system for draw and update calls is working beautifully and is stupid easy to work with. Time to finish up the draw logic so we can start making a proper game, right? So by Monday, January 8, 2014 I want to finish up the code for drawing objects with arbitrary size and rotation and finish the resolution scaling code so that the screen is centered properly. Once that's done, you wont have to read any more of this technical jargon, which will be replaced with talk about doing some honest gameplay design. See you then, Jammerinos.