Friday, February 17, 2012

Bad Architecture 101

Finally, the poor design of Kaiken's internals is giving me headaches.

For a while, the sloppiness gave me no real troubles. But now, the various design flaws are starting to make progress difficult. My main goal tonight was a tough problem, one I should have saved for a day when I've done enough coding to get back into the groove, one that could have waited until I did some study on the subject and potted a reasonable course of action.

Instead, I dove headlong into frame-rate independent animation and movement. Up until now, Kaiken was strictly based on frames. Every frame, tell the level to update itself, which would, in turn, tell each object in that level (players, enemies, etc.) to update itself. These updates include such key things as changes in position or momentum, as well as checks for collisions. Everything was perfect; every frame, tell each object to move based on its momentum. If the momentum was {5,10,0}, the object would move 5 pixels to the right and 10 pixels up before the next frame was rendered.

This simple design is easy to code, but it has flaws. The biggest being that not every computer runs at the same speed. While modern computers can chug through the entire update and render process at about 3 to 6 milliseconds, this shouldn't be counted on. If the system is under load, it may take longer, and when the game slows down, it literally slows down. Even under optimal circumstances, there are subtle variations in games speed.

The rate the game runs at should not have an impact on how fast objects move in the game. Even running at 20 frames per second, an object should cover the same area as an instance of the game running at 60 frames. It will look choppier, but appear to be going the same speed.

The simple way of doing this transition (if one does exist) is to, rather than move the object by its momentum every update, move the object by its momentum multiplied by the time that has passed.  Find the number of milliseconds that have passed since the last update and make that a factor in how far the object will move in the current update.

A simple concept, truly, but it changed an entire portion of my shabby little engine, most notably the Physics class. This class is simply a bunch of functions that can be called to handle collision checking and movement. For instance, the move() function would take an object and add its momentum to its location, thus moving it to a new location based on how it was moving. The function now also accepts a number of milliseconds, which is now factored into this equation. No big deal.

Too bad the rest of the functions weren't this easy. Applying friction and gravity this way will require a complete re-write of these functions. Well, I guess that isn't completely honest. I've got gravity working pretty well, but friction isn't going so great, but I've got a couple ideas up my sleeve.

On the worst end is my collision checking code. It checks the momentum of the object in motion to guess what its previous position was. Because the momentum is now pixels per second, not pixels per frame, it's allowing things to get inside other things in a way nature never intended. The way I do physics will have to be completely different. Perhaps I might get it working by storing the object's previous position instead of trying to backtrack it with momentum.

Hopefully Kaiken will be more robust and clean by the end of this disaster. I'm not expecting that to be the case, however.

Sunday, February 12, 2012

Introducing Project Kaiken

I lied.

My concerted effort to learn Nintendo Entertainment System assembly programming lasted about twelve hours: long enough to get a development environment set up, burn through some tutorials I've done before, and write a blog post about how "gung ho" I was.

It wasn't long before reading those memory maps began to eat away at my enthusiasm. Pattern Tables and Attribute Tables again reared their ugly heads and beat my motivation to dust. I turned my back on NES programming and went back to make serious efforts on my initial game engine project, written in C++ and using SDL.

I won't beat around the bush: this game engine sucks. It has "purely academic exercise" written on every pixel it renders. That said, great improvements have been made on it.

I was reminded that STL data structures exist and many, many places have seen <vector> and <list> added to clean up my sloppy-ass data management. While not ideal for high-performance gaming, it's much better than what I have been doing. Memory leaks have all but disappeared by using these tried-and-true classes over my disgusting solutions. Multiple sound effects can be played at the same time, and music tracks can be changed.

The engine even became stable enough to run more types of demos. A title screen is now present, as well as a basic platformer.

Not everything is sunshine and daisies however. Despite the code cleanups that have occurred and the new features that have been added, many key things are missing. In fact, calling it an "engine" at all is being quite generous. Everything is hard-coded except for the graphics data (images, fonts) and audio data (level music, sound effects). Not only is it impossible to add or adjust levels without recompiling the entire thing, but even simple things like controller configuration aren't possible. There is no simple way to do animation, levels have to be programmed 95% from scratch, and things such as gravity and AI are programmed into the levels, limiting code reuse and increasing programming difficulty.

Lots of things need to happen for the project to continue in a nice fashion. A short list would include and easy way to load a sprite sheet, define the animations that are included, and call for them to happen in-game. Not to mention that AI and gravity need to be broken out of the level's code and into their own for easier referencing (which is preferable over the copy/paste method). Some way of creating levels as external files would be great, but that's not a short-term goal right now.

Of course, once these things happen, then it would be nice to have a game concept to bring to life using the engine. I have a couple of rough ideas, but nothing solid or "fun" yet.

I'm not averse to going back to NES programming. Frankly, it's nice to have a final binary under 256 killobytes that I can easily send to people. Kaiken is a fat-ass project by comparison, the executable binary weighing in around a megabyte on its own, then there's the several megabytes of DLLs it depends on, and the megabytes of graphics and sounds. '

I haven't worked on this project in a couple of months now. In fact, I haven't really been doing much programming at all during that time. It's a fun hobby I ought to get back into. Maybe something good will come out of it.