Happy Halloween! Before the clock strikes midnight and we all turn into jack-o-lanterns, there’s time for just a few last-minute features in this game engine / editor I’ve been working on all month.
First we have some animation, as shown by the animated GIF up top. One of the nice graphics bits that I always liked in the Ultimas was the animated water, so I decided to put in something similar. It’s an easy effect, since it’s really just shifting the pattern by one row each time it gets drawn.
This also gave me a chance to write the only assembly language code I’ve done for this particular project. While everything I’ve written so far has been strictly procedural with a single thread of control, the animation is handled by an interrupt routine. The interrupt is triggered by the VIC-II graphics chip at the bottom of each frame. Every fifteen frames, the water image is shifted one row down.
How do I find all the water tiles on the screen and animate them? I don’t have to. Remember, each kind of tile is stored as 4 characters in the custom character set I’ve created. Instead of updating the map at all, I just have a routine that’s hardcoded to find the entries for those 4 characters in the character map and change the source data. That’s only 32 bytes of data that need to be shifted for the effect to work, no matter how much water is on screen!
I’ve also put in some very-quickly-prototyped gameplay. In my image quality comparisons you saw that I had a woolly mammoth on screen as well as the spear-wielding hero. Before the end of Retrochallenge, I really wanted to be able to kill that mammoth.
The first step was to give the mammoth some kind of behavior. Obviously I’m not going to have CPU time or RAM for any really sophisticated AI, but I don’t think that’s necessary for this kind of game. Instead, I gave the mammoth some simple behaviors based on the Manhattan distance between the mammoth and the hero.
It works like this: If the distance is 1, the two entities are adjacent, so the mammoth tries to attack (at this stage it really just prints, “mammoth attacks!”). If the distance is less than 4, the mammoth moves closer to the hero. And if the distance is greater than that, the mammoth will just slowly wander in a random direction.
The “move closer to the hero” logic is actually a bit tricky. Diagonal moves aren’t allowed, and in my first implementation the mammoth always tried to move left or right to get closer to the player before it tried to move up or down. This led to a weirdly “mechanical” sort of motion that I didn’t like. For example, if the mammoth was one square north of the hero, and the hero moved left or right, the mammoth would always mirror the hero’s action, blocking them from going north (unless terrain got in the way). I changed the movement so the mammoth would randomly decide whether to try moving horizontally first or vertically, and that gave it a more “organic” feel as it chased the hero around the map.
The hero, meanwhile, gained a real attack action. It takes a lot of shortcuts – it always hits, and always does a fixed amount of damage – but I think for the full project I might want to go for a different kind of combat altogether, so this is just a prototype. Mainly, it let me check that monster hit points were working as expected, and that I could kill something and remove it from the map without crashing the program. These are important considerations, after all.
So now I’m at the point that I’m calling “done”, at least for this Retrochallenge. I’m going to try to get a video up on Youtube showing off the various features, if I can coax my ancient iPhone into cooperating. I’ll be sure to post here when it’s ready.
What’s next for this project? Well, I’ve got other hobbies and other projects that I’ve been neglecting, so I’ll probably set it aside for a little while. So I’m going to make an early commitment for the next Retrochallenge to pick up this project again and take it another step. At least, unless I get a better idea in the meantime!