Monday, June 25, 2012

Kaiken Lives, Sort Of

It's been a long time since I last touched Kaiken. Whether it's because I haven't been in a programming mood, didn't want to deal with all the corners I've coded myself into, or sheer laziness I can't say.

Regardless, I've been working on it since last night and have actually made some impressive progress. Well, impressive to me and only because of the time I've spent coding nothing and the short amount of time I worked.

The biggest thing I fixed was the Box Collision detection code. I use it for detecting when an object is touching the "ground", or a platform they can stand on. I decided to just rewrite the entire function, this time for readability and not minimum line count. While I could now understand what the function was trying to do, it still wasn't working. I traced the problem back to the way I calculated objects' previous positions.

I had been "reversing" the player's momentum to figure out where they'd been last. However, since a collision with one block would change the momentum (to prevent them from smashing through a wall instead of being stopped by it), this became unreliable when touching two blocks simultaneously. The first detected collision would return "Hey, he landed on top! Better stop him from falling!" and the second would say "Well, he didn't FALL here, he has no downward momentum! He must have collided from the side!". This would cause the player to be stopped by blocks he was standing on as if he was running into them. Not cool.

I needed a better way to figure out the previous position of the player. What I needed was a variable that stored the previous position reliably. It would need to be updated automatically whenever the player moved, perhaps in the function that moved the player.

For a while, I pondered how to implement such a system. Then, I dug through the code only to find that I'd already been doing this, but my collision code wasn't using this information. Sometimes I feel like a dumbass. This instance went well beyond that.

So the collision detection pretty much works, but when colliding against the left side of a block, there's a little weirdness. At this point, I don't care; I'll fix it later.

The next morning, I implemented a Goal Block. When touched, a congratulation message is displayed and a countdown begins. At the end of the countdown the level ends.

I can't believe how easy it was to fix this stuff. Hopefully after work I have the time and inclination to keep working on it.

Sunday, April 1, 2012

Lurid's One-Eyed Monster

After some fierce debate, I decided to point my alignment in the Law direction.

Demons work best when their alignment matches yours, so it was time to let my Pyro Jack sink to the bottom of the roster, rather than dominate the top. For too long I failed to realize how poorly he fit my play style at his current position in my depth chart. Myself being a mage and gunner combo, all his shots did was block my chances of shooting. We had to take turns, preventing each other from acting in a timely way.


Living in a post-apocalyptic world is no excuse to ignore good fashion sense! Hee-ho!!

As much as I'd miss our matching hats, it was time. He'd leveled quite a bit more than demons are intended to, and I needed something that better complemented my ranged combat style: I needed a strong, melee-based attacker. Someone who could act as my shield or  quickly swat off incoming targets.

My first choice was Taraka, a huge woman with four sword-wielding arms. This worked out pretty well, lending powerful swings to finish wounded enemies and enough defense to shield my retreats (in theory, as far as you know...).


Also, she was a hit at parties. Bachelor parties in particular.

Taraka, however useful, was a pain to summon, costing about 1500 magnetite with each expulsion from my COMP. I needed a Fighter, but I needed one of the Law alignment.

Reluctantly, I fused my Taraka and got Ogre.

Immediately, I wanted to nickname him Shrek, trite as it would be. Then I noticed something strange about the layered demon:


Lawful Evil. Like Darth Vader, or the guy who's always trying to screw Native Americans out of their oil-rich land.

I know from my AD&D games that Good and Evil have nothing to do with Law and Chaos. But still, this is a seldom-seen alignment combination. Not something I expected, but hey, wait, what are you doing STOP THAT THIS INSTANT YOU HORRIBLE BEAST WHAT THE HELL IS THE MATTER WITH YOU!!?!?


Is "horny" subtle enough to be used in a double entendre? Probably not.

Okay, so the strange alignment wasn't the thing that really stuck out with me. But hey, at 62 magnetite per summon, I can't complain. As long as he doesn't turn that horn of his (either one) on me...

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.