(Blog is in chronological order. Latest post at the bottom.)

Quest! for the Gumdrop of Destiny now online

11.jan.2021

Oh, no! An incredibly stupid web game where you click on a button and it determines whether you kill a slime or the slime kills you.

It's all completely random. You either kill, die, or run away to kill and/or die some more.

Play it here.

I'm going to try to add a combat and points system, if I can figure out how. At least make it so that you encounter more than just the same slime, over and over.

Every time you click Attack!, your chances of being killed are 2 in 10, a 5 in 10 chance of killing the slime in one hit, and a 3 in 10 chance of only hurting the slime.

Clicking Run! gives you a 3/10 chance to escape, 5/10 chance of being blocked, 2/10 chance of being killed.

  

Quest! has been updated to version 0.2

12.jan.2021

Up to version 0.2 of my game. I found a simple engine from a user on Reddit and I've been hacking some features into it.

In this new version, you are now an adventurer tasked with retrieving the Gumdrop of Destiny from the Cave of Candy, but you have to watch out for spiders.

It's still basically a "Choose your own adventure" type deal, but I'm trying to add more gamey elements, like an inventory system with a set number of torches and matches, a hidden key you have to find, some combat stuff with random encounters (because spiders, etc.)

*SOME TIME LATER* - Ok, I took a break, came back and tried to play through it a few times. It's hard for me to be objective because I already know how to solve the puzzle but I went ahead and added some randomness in to really mess with the player.

I don't want to spoil it, but there's only one way to solve it, and it depends on chance. If you're on the path, go South into the woods. If you're following the river, go North into the woods. The only way to get past the spiders is to get lost in the woods.

Once you are lost in the woods you have a 2/8 chance of getting killed by spiders, a 2/8 chance of staying lost, a 2/8 chance of getting back to the path and a 2/8 chance of getting to the river. You want to hope you find your way back to the path in the woods.

Once you've gotten lost and found your way back to the path, you have 3 choices: either get lost again or follow the path in one of two directions. Pick a direction; I won't say which one, but if you think about the layout of the map, the answer should be obvious.

The correct choice leads to the Cave of Candy. The wrong choice leads to death by spiders.

And that's it. It's a little unfair, but the odds are in your favor.

  

Graphics engine rewrite

13.jan.2021

Just finished rewriting the "graphics engine" for Quest for the Gumdrop of Destiny. Expanded the view so it's a lot less claustrophobic. (not to be confused with Santa Claustrophobia, of course)

Also rewriting the first section of my game because I keep coming up with new ways to do it, and every single time, I'm like, "There's better, less hacky ways to do this... I know there is. If only I knew how to code."

I mean, this is the hackiest, dopiest way to do a thing. It's like early web bullshit when no one had any idea what they were doing. It's just a big table with a picture in it... And every time you click "East," it loads the same table with the same picture but the picture is now one cell to the right. And I'm just laughing at how silly it is that it actually works.

I can't wait to finish this thing so I can get it out of my system and never think about attempting this again.

  

Quest! world map, expanded view

13.jan.2021

Full view of the Quest! world map:

It looks simple, right? Like, you can just walk East and straight into the Cave of Candy, right? Yeah, I did that on purpose. One does not simply walk into the Cave of Candy.

*mfing spiders!!!*

  

Random encounters

14.jan.2021

"Can your game do random encounters?"

Yeah... I can do random encounters.

You now have a 33% chance of being murdered by spiders EVERY SINGLE TIME you take a step -- which is, admittedly, rather excessive.

I'm probably going to tone that down and make some spots neutral ground.

I'm also thinking of hiding a magical blade somewhere that makes the spiders stop attacking you, but I want to keep the spider trap on the path. (That's my favorite part!)

Haven't pushed this out, yet. Probably won't be ready for hours.

  

Frustration: switching to GDevelop

15.jan.2021

I'm finally hitting the point where this is no longer fun, and I've become frustrated at my own limitations in programming a "game engine."

I long ago abandoned the simple engine I found on Reddit and began using CSS hides to move content around. Essentially, the game was a large table - 16 cells tall by 24 cells wide - with a PNG image of each "sprite" in the appropriate cell with the background color set to brown and green to look like dirt and grass.

Every time the player would click a direction link, it would load a new table with the images shifted one cell in whichever direction the player clicked. That's it. Pure trickery. No skill, brute force.

As you might imagine, putting that together had become incredibly tedious. There were approximately 70+ moves that could be made, requiring me to hand-format each table 70+ times to make the character sprite move around the map. The size of index.html had grown to more than 2 MBs (!) in size. (As of January 19, this version is still the most curent version, however...)

I reached my breaking point when I began coding the Cave of Candy.

For the Cave of Candy, I had a maze laid out and ready to go; only needed to build a table for each possible move. But this new layout meant coding more than 100 possible moves for the player to make -- and most of them obvious dead-ends. It seemed foolish to make tables to include player the user would never take if they didn't need to (because you could plainly see where each path went) and it was taking me hours to get even halfway done. 5-6 hours? I lost count.

Since the scope of this game had now grown beyond a simple point-and-click adventure, and the prospect of spending the next eternity making tables, I decided to switch gears and focus on learning how to develop games the modern way. I turned to GDevelop.

I had a couple of options to go with, but GDevelop jumped out at me, and the examples looked much more in line with what I wanted to accomplish. In fact, in on one hour, I’ve already built the existing game world, animated a character and got it to move around. I even set it up to work like the release version currently available. I'm already lightyears ahead of where I could possibly hope to be with developing my own game engine, and I don't even really need to know how to code! Honestly, I'm not trying to invent a killer app or become a professional web/game developer, I just want to finally realize a childhood dream of creating my own video game. Even if I'm the only one who ever plays it.

We'll see how far this gets me, now...

  

Breakdown

16.jan.2021

I've come to the conclusion that I am fucking stupid.

Like, I don't know where I fall on the spectrum of, like, intelligence, but I am not. And that explains a lot of things.

I have no other way to explain how I have tried and failed to learn how to program in 25+ years. From sitting at a Tandy in my parents' den, hacking away at BASIC, to this very moment... I even went to college *specifically* to learn how to program in languages such as C++, Visual Basic, Java, and JavaScript, and I still cannot do it. (although, that college was a waste. Let's not forget that.) I'll argue that I did learn a lot of PHP and MySQL on my own for various projects, but even then, I had a lot of help from people much smarter than myself. Which just reiterates the fact that I must be stupid. My brain is broken. It explains so much about my trainwreck of a life.

I just... I don't even know, anymore. I should just quit before I embarrass myself any further.

  

I'm back.

16.jan.2021

I was literally crying after spending hours and hours trying to make a Zelda style, top-down RPG. I wanted to recreate the "shifting room" effect as seen in the original Zelda for the NES. If I recall, it was actually a limitation of the hardware that lead to that, but I really wanted to incorporate it into my game instead of having a large, fluid world map. So, I watched a tutorial on how to create this effect in GDevelop and... yeah. That guy's example won't really work for my game.

In his example, when you pressed a directional key, you would create a sprite that would advance one screen width in the direction pressed. Then, a hidden pathfinding sprite would move to that location at a set speed with the camera following that sprite, keeping it centered in the frame. It was a marvelous effect that worked extremely well, but the method wasn't good. How does the player character move around within the room if the room shifts based on which key the player was pressing? A decent work-around simply eluded me.

Trying to find a way of recreating this had me grasping at straws, trying everything I could, and just failing again and again until I finally broke down in tears. I don't know what else to try. This just won't work; I have to fall back on a different method. It's just so frustrating to feel like I can't get this. How many rock-star game developers out there have the same story of turning on a computer, and then suddenly they're the next John Carmack, or whoever? I've read so many of these stories... How do I just never learn how to do even basic shit? I'm so fucking angry about this.

Nailing this was pretty important to me because I liked the feeling of suspense in the original Zelda... The idea that anything could be waiting for you on the next screen. Each "room" had the potential for action, suspense, mystery, or tragedy. It made the world feel huge by only allowing you to see so much of it. But I'm going to have to abandon this idea and fall back on having a camera squarely centered around the main character, following you around. It's fluid, but it still compresses the scope of what the player can see, and what happens in each "room." It's just all I've got, for now.

  

Breakthrough

17.jan.2021

HOLY FUCKING SHIT, I FUCKING DID IT!

I GOT THE FUCKING ZELDA EFFECT TO WORK!

And not only that, but my new method works EVEN SIMPLER than the version I found online!

As I said yesterday, I kept trying to figure out a way to get the camera to shift one screen in whichever direction the player was exiting the current screen. Nothing I threw at it would work. I had an idea to track the distance, in pixels, of the player character's sprite in relation to the center of the screen. But it just wasn't working. And then, I decided to start from scratch.

I created a new scene and set my resolution to 320x240 (for aesthetic reasons, I'm keeping it close to the res of the NES). Then I set a sprite at the center of the screen called "camsprite." Here, center position is X,160 by Y,120.
Next, I set up a condition: if the X position of the player sprite is greater than 160 pixels of the X position of the camsprite, move the camsprite 320 pixels (one screen width) positive -- because anything higher than 0 is to the "right," or East on the map. To go left, simply check to see if the X position of the player sprite is less than negative 160 pixels and move the camsprite negative 320 pixels. The same goes for up and down; just set conditions to move the camsprite depending one where the player is standing in relation the Y coordinates of the camsprite. Greater than or less than 110 pixels from the position of the camsprite. But the next part is the money part...

From a tutorial on getting the camera to follow the player sprite, I learned about lerp.

The code you want looks like: lerp(Camera.X(),Player.X(),0.05). The first variable is the X position of the camera. The second one is the X position of the player sprite. (And the same is true for tracking across the Y axis. You just use Camera.Y,Player.Y instead of X.)

What this does is the game constantly measures the distance of the player sprite and camsprite objects and moves the camera along the X/Y axis towards that point at a set rate. In a side-scroller, it gives the player sprite some "wiggle room" so that the camera isn't directly centered on the player the whole time. If it were, the game would feel stiff and robotic. Instead, it allows the character to move a few pixels before the camera begins to follow it, giving you the impression of moving within the frame of the picture. It's a classic effect that's been in every great platformer you could think of, but here, I'm using it in a top-down perspective to get the classic Zelda room shifting effect. The camera now "pans" smoothly from room to room rather than sharply snapping into place.

It just works! I can't belive I finally figured it out!

  

Addendum

17.jan.2021

In addendum to my last post, here's what it looks like to have room-based design for a top-down RPG:

Not only that, but I managed to get some enemy AI in there. The spiders will chase you if they see you; however, they tend to clip right through the obstacles meant to keep them in place. I'm not sure how to get around that, and I'm not sure I want to, since the enemies in Zelda were pretty dumb and just marched about in mostly straight lines. I want to keep this simple, so I might pull that out.

  

The Birth of Khaki Jack

18.jan.2021

We have a new name! Khaki Jack and the Quest for the Gumdrop of Destiny!

Well... for now.

Following yesterday's breakthrough, I'm now free to focus on creating the world my game will take place in. I'm not done -- not by a long shot -- but getting those basic fundamentals was a good portion of the battle. Getting the look and feel of this world was paramount, and the way the character exists in this world defines a lot of what that look and feel will be. I mean, I've even got sprites with animations that change depending on which way Jack is walking. This is huge! And it all depended on nailing that camera movement... Now that we can chop Jack's world up into bite-size (or, screen-sized) pieces, I can focus on building one room at a time for an overall more consistent look and feel.

Speaking of, here's what my game world looks like, so far:

Right now, you can't really do anything but walk around and get killed by snakes and spiders, but it's something!

Also, I pulled out the "seeyou" enemy AI. It was pretty neat, not gonna lie. Having the enemy be able to follow and track the player if they should wander to within a range of, say, 100 pixels or so had a great effect. I might add that in to some other enemies if I can get it to behave better, but for now, I have the snakes and spiders "leashed up," running around on set paths so that they can't just wander off.

ALSO also, I have theme music! I just felt like composing some theme music, so that's what I spent a few hours working on, this morning.

  

Meet Khaki Jack!

18.jan.2021

Khaki Jack - at idle.

I'm an artist... not a GREAT artist, but I make art.

Khaki Jack - walking.

Trust me, it looks better in-game.

  

More snakes and spiders! Plus, health and damage!

19.jan.2021

I'd like to say that we are cooking with gas, now. Each day I learn how to implement something new, and today's victory came at the implementation of a health and damage system. Khaki Jack can even be killed, now. It's huge...

I wanted to start making the first dungeon today, but I felt like it was more important to get a working health and damage system, first. Because if I couldn't figure out how to do that, this game's development would be dead in its tracks.

Originally, Jack was just being insta-killed by whatever came his way. Snakes, spiders... death. And that's not fun. Who wants to explore a world that never lets you go beyond the opening area?

What I needed was a health and damage system; something that gives the player a little bit of forgiveness so that they can venture out and explore, but I needed to learn how to do that. This was what was holding me back in all of my previous attempts at building a game.

In fact, one of the biggest hurdles, and the real, actual, number one reason I started using GDevelop was because I couldn't figure out how to make a damage system in JavaScript. I mean, sure, in concept, it's easy -- you create a variable for "health()" and set it to equal 10. Then, when something hurts you, the formula is "health() = health() - 1."

Seems simple enough, right? But I just... I couldn't get this one simple thing to work with what I had built. The formula works, but I don't understand enough about coding in JavaScript to make it pass variables between page loads. I could have spent hours and days trying to figure it out, but going back to what I said a few days ago, that's just not me. That's not my talent. I'm a terrible programmer. I'm simply incompetent. Even after screwing around with coding for 25 years, unless someone shows me how to do it, I can't do it. But GDevelop makes it easy! (well, easier. I'm still struggling my way through this.)

I followed a simple tutorial and had the damage system up and running in less than an hour.

Now, Jack starts with three hearts. He loses a heart each time he takes damage, until there's none left. Then you get a GAME OVER screen. However, if you can find a potion before you lose your last heart, you get one heart back. And it works! All of that. Everything I just said; it's working in this game!

So, again... yeah... Someone needed to show me how, first. (I mean, I'm still new to GDevelop; I've only been using it for less than a week) But now that I understand how, I'm there! I have a working system! Jack can be hurt; Jack can be healed. Jack can even die! It's looking more and more like a game instead of a madly hacked web page. Just a few more concepts to figure out, and then I can really knuckle down on building this game's world.

  

BG Music and Title Screens added

20.jan.2021 15:00 hrs

Last night took a slight untentional detour as I shifted away from working on the game to compose some more music.

I want the music for Khaki Jack to be as close to classic Nintendo music as I can get, so I went looking for a virtual instrument that can replicate the sound chips used in the Nintendo Entertainment System. What I found was the Nintendo VST by Matt Montag, and it sounds incredible!

This isn't my first time attempting to recreate the sound of chiptunes (I first came across the chip scene and MOD/tracker scene back in 1998), nor is it my first attempt at creating game music, but it's the first time I'll actually have my music in a game. That said, I was looking for pointers and tips on how to successfully recreate some of those iconic tunes from the 8-bit era using modern software (namely, Ableton Live and the aforementioned Nintendo VST.)

Matt not only supplied the VST, but was generous enough to provide links to a wealth of information on how to get a wide variety of instruments and effects using the same parameters and techniques used by the classic masters. Again, I'm in awe at what developers such as Sunsoft were capable of creating on the meager hardware, and the genius of Koji Kondo when it comes to creating truly unique and iconic soundtracks. I can only hope to acheieve even a fraction of that honor.

I'll have mp3s of the music up, eventually. For now, back to the grindstone. We now have a title screen to go with that title music!

  

Progess Video - Melee attacks implemented

20.jan.2021 23:00 hrs

It's been several hours since my last post... Here's a little peek at what I've got finished, and some of how the game works. As you'll see in the video below, there's a title screen, then I kill a spider, grab some health potions, then get killed by a snake. (apologies for the "shaky cam" video, btw. I might redo this clip using a screen recorder on my desktop in the future.

To understand how I got here, you need to take into consideration that I had to remove every bit of progress I made on the "movement" mechanics until it was back to a blank state. Stripped it bare.

First was the issue of getting Jack to face whichever direction he was previously walking in. Originally, it was pretty simple: if you push "left," Jack moves left while the "walking left" animation would play. But as soon as you let go of the left key, the sprite would snap back to looking "down," or South. This would not do.

In order to get Jack to attack in a particular direction in top-down perspective, I needed to code the game in such a way that it would "remember" which way he was last facing. To do that, I insterted an instance variable into the Jack object and called it "direction." I tried doing this several different ways before settling on using numbers 0 through 3. 0 = down (or default), 1 = up, 2 is right, and 3 is left. (It would have been far less confusing to use the names of the actual directions, but there were a number of other things at play, here.)

Now that the game remembers which way you were last facing, the trick was to assign a "walk" animation and an "idle" animation for each direction. Left and right could be mirrored, but up and down would need to be two separate animations. No problem!

Eventually, I got it all working as expected. Time to move on to the combat animations.

At this point, it was simply a matter of looking up those direction variables and checking to see which way the sprite was facing. Left and right could use the same animation simply by flipping it horizontally, but up and down would require — you guessed it! Two new animations. One striking towards the top of the screen with Jack's back to the player, and one striking downwards with Jack's face facing the player. It worked swimmingly!

Unfortunately, in my haste to strip out the original directional code, I took most of the combat system I had just added with it. I needed to re-add a hitbox sprite to interact with the enemies in the game when you hit the "attack" key, re-add the code that damages them until their health equals or drops below zero and then delete them when it does.

Of course, none of that worked after I put it back in. Some parts were missing, some parts were wrong, some parts just didn't work like they had before because of the new direction code. From roughly 3 pm to 11 pm, I reworked the code again and again to track down the bug. I was beginning to get exhausted and very frustrated.

In the end, however, it works. The results are what you see in the video above. All except for ONE thing...

Currently, the issue plaguing me is the whip animation. It seems to execute only the first frame, and I'm not sure how to fix that. I had it fixed with the original code, but then I broke it with the new code. I don't understand what's happening. I've been going over it again and again, and I'm still unsure as to what it could be. The speed of the animation is fine, it seems to be something with the way you get to the animation, like it's only playing as long as the key is pressed down? But even that doesn't seem to be it. I'm stumped!

So, that's where we are. The movement system works, the combat system works... If I can just figure out this animation problem, I can move onto the next thing on the list.

  

Attack animation bug squished.

21.jan.2021 12:00 hrs

After a lot — and, I mean, a LOT — of digging, I finally nailed that animation bug.

It came down to making sure that the attack key could trigger the attack animation only once, and that the attack animation finished before reseting the attack variable to zero. Now, the entire animation plays and resets after one key press — even if you hold it down. The condition also remains true when holding the key down so that a collision occurs only once and doesn't constantly deal damage to an enemy.

What remains to be seen is how all of this is going to be affected when I attempt to add other weapons and attacks to the game.

  

Character/animation redesign - Meet Khaki Jack 2.0

22.jan.2021 11:25 hrs

After squishing the attack animation bug, I ended up with a migraine headache, and desperately needed to get away from the computer for a bit. I used the time to finish watching season 1 of The Expanse (finally, after 4 years, I'm back where I left off) and just relax.

Of course, that only worked for so long.

Eventually, I took a break from that and watched some YouTube videos on character design and pixel art, and that got me inspired enough to redesign Khaki Jack and fix a few things that were bothering me about his look.

First of all, I gave Jack more of an "S" curve posture to give him a bit of "swagger," and a stance that says, "Laid back, but ready to go." Then, while I was in Piskel, I decided to animate it, and accentuate that feeling, overall. Here's how that turned out:

Of course, this means that I have to rework ALL of the animations to fit with this new look and feel. So, here's his walking sequence:

At this point, his idle and horizontal walking animations are complete. Still left to do: walking "up,", walking "down," and all four attack animations. So much work that I hardly feel competent enough to do, and yet...

A fun thing I've learned about solo game development is that, if you ever get bored with one role, you've still got about fifty others that you need to perform. One day, character design. The next day, animator. Day after that, music, sfx, coding, level design, play testing, etc. At least he doesn't look like an alien cowboy, anymore.

  

I hate to see you go, but I love to watch you leave

22.jan.2021 13:00 hrs

haha... on, no... I may have inadvertently given Jack an ass...

Totally unintentional, just some necessary shading. And yet, I'm definitely not going to change it.

  

A N I M A N I A C A L

22.jan.2021 16:00 hrs

I am very, VERY pleased to announce that ALL NINE of Jack's animation sequences are now completed. Idle facing up, idle facing down, idle facing right/left. Walking up, walking down, walking to the right/left. And, finally, attacking up, attacking down, and attacking to the right/left.

And they all look pretty damn good... if I don't say so, myself.

  

Tabula Rasa

22.jan.2021 18:30 hrs

I figure now is as good a time as any to call it a day. Considering that I pretty much took the day off, yesterday, I feel good about the amount of work I got done today.

With the animations complete, I decided that I would start work on the first dungeon, since that's something I've been wanting to work on for a while. You know... as a treat.

Unforunately, this also meant taking a crash course in how GDevelop handles things like global objects, variables and the like. And, wow... that was a real quick venture into headache country.

At first, I was afraid that I was going to have to copy and paste each event from the Overworld scene into the dungeon_one scene. And if I had to do it for that scene, did that mean I would have to do it for all future scenes? Well, no. Thank goodness I didn't have to do that!

No... Instead, I only had to copy them all into an External Event sheet.

Was this going to be a big pain in the ass? Not really, no. Was there plenty of potential to completely bollocks it up, though? Yes, definitely. I was starting to sweat.

Fortunately, I got everything copied over. Now, all I have to do is link the External Events into each new scene I make, and they'll all magically work. All the events for each key press, triggering animations, all that good stuff.

And it certainly makes sense to do things this way. Imagine, for example, you don't want a condition to be universal across the game. Like, background music shouldn't be the same in each scene, but sound effects should. So, background music remains internal to the scene it's meant for while sound effects go into the External sheet. Maybe you want the mobs in one scene to be pretty easy while making them tougher in other scenes? No problem! Assign their hit points accordingly in each scene they appear in. However, the code that determines what happens when you hit them should be the same across the whole game, so that's a global thing. Pretty neat!

And that's where I'm calling it, for the day. I have one room of the dungeon finished that you end up in when you get Jack to the entrance of the dungeon. And, as expected, exiting the dungeon takes you back to the overworld. Or, rather, to the beginning of the game... which means I now have to figure out how to get Jack back to the spot where the dungeon is rather than the starting point of the overworld map. D'oh! Save it for tomorrow's tasks.

  

Caves are the new dungeons

23.jan.2021 11:30 hrs

I had just wrapped up building the first room of the first dungeon when I suddenly remembered, these are supposed to be caves. So, we're not doing dungeons. We're doing caves and temples. It's different.

Jack is an "adventurer," combing through the jungle for a lost treasure; not a hero in a high fantasy setting. LOW fantasy, maybe... but not high. Which meant the tileset I had also spent an hour or so creating was now kind of a waste. I decided to hang on to them, just in case.

One of the neat tricks I managed to pull off was shading one half of each tile by lowering the value of the colors in the palette I had settled on. The goal was to give the impression of depth by making it appear as though the walls were inset for a 3D effect. I originally wanted to add perspective lines, achieving the same effect by angling them inwards. I still could have, of course, but it was easier just to paint one half the tile darker than to go back and forth trying to make sure the lines all matched. It worked a charm!

Next up, instead of making tiles that looked like stone walls and masonry, I had to create a new tileset that looked like rock walls and dirt paths.

  

Crash and (thankfully) no burn

23.jan.2021 18:00 hrs

Experienced my first GDevelop crash. Hoo, boy... Thought I lost everything.

I duplicated the first dungeon scene to begin building the first cave scene. I deleted an asset I no longer needed after spending several hours designing the layout and creating a tilset for a dungeon I now no longer needed (remember: we're not doing dungeons, anymore) and GDevelop froze up, claming that the Overworld scene no longer existed.

Well, naturally, I panicked. GDevelop auto-saves, and even then, I had saved my progress before duplicating the dungeon scene (years of experience losing everything to a file corruption taught me well) so I figured everything was going to be ok. The idea of losing everything I'd worked on for the past several weeks, however, threw me into a cold sweat.

I tentatively shut down the program, skipped trying to save before shutting it down, and then, when I reopened it... everything was fine. It was as if nothing had happened. It even remembered that I deleted that asset I no longer needed. Work continues!

Side note: I recently bought a used TurboGrafx 16 from The Game Store in Wilkes-Barre and a copy of "Dungeon Explorer" on eBay. Someday, I'll go into what actually precipitated this foray into game design, but a big part of it was playing old adventure games and wanting to finally fulfill my childhood dream of being a game designer when I grew up. That's the short version, at least. Anyway, "Dungeon Explorer" arrived in the mail, today, so I'm looking forward to trying that out. But first, I have my own dungeons -- *ahem* caves -- to explore.

  

Gone batty

23.jan.2021 21:00 hrs

Cave One is off to a good start! We've got boulders for obstacles, rock walls, dirt floors, and -- BATS!

The first enemy you'll encounter will be a group of bats that have been trained to follow you around. They deal out about 25% damage when they hit and will follow you throughout the cave if you either can't outrun them or dispatch them soon enough. Lots of fun!

Check out the screenshot below for a map of what I've completed, so far.

On another note, I had been struggling since I began this project to understand why my game looked so... awful. I know I'm running at a resolution of 320x240, but the scaling shouldn't be as bad as it looked. I've seen other GDevelop projects with 32x32 pixel sprites, and that used 16x16 pixel tilesets... What could be wrong?

As it turns out, I had filtering and anti-aliasing turned on, using near-pixel matching to smooth everything out. As soon as I turned it off, everything looked as it should. All that beautiful pixel art, clear and sharp. I'm so relieved I won't have to start over on a high-definition version.

  

SECRET TUNNEL!

24.jan.2021 9:22 hrs

Work on Cave One progresses. Just thinking of all the cool stuff I can add in there. Like, booby traps, and... secret tunnels!

  

Just for shits and giggles...

24.jan.2021 9:59 hrs

No secret tunnels, yet, but just for shits and giggles, I made little cave rats that scatter when you get too close. You can't kill them, and they won't hurt you... they just scatter like crazy until you're far enough away.

I like 'em... They're cute! Adds atmosphere.

Update: 14:00 hrs - The rats no longer randomly scatter everywhere. I came up with a useful purpose for them, after all.

  

We have a secret tunnel!

24.jan.2021 10:20 hrs

Ok, secret tunnel has been added! And now that we have a secret tunnel, it's time to make every other path ugly as hell. The idea is to incentivize exploration, and get players to think about alternative paths -- even if they are hidden in plain sight. The question is, how do I get the player to find the alternative without making it glaringly obvious? I think I have an idea.

  

It's a no brainer...

24.jan.2021 13:00 hrs

Jesus... that was something. 3 hours of struggling to add some simple dart traps.

I'm not even going to go into detail of why, or how, that was such a complication, but it's done.

The dart trap room isn't perfect, it's not exactly what I wanted, but in the words of Doug Marcaida... IT WILL KEAL.

The whole point of it is to make the straight and narrow path as undesirable as possible. I want to encourage the player to explore, to look around for alternatives, to use cunning instead of brute force. I don't know if it'll work, but it's fun to try!

So, now, the player has options. They can choose the straight and narrow path — and get tenderized into hamburger. Or they can look around and take the secret tunnel that rewards them for taking the time to explore by not outright killing them.

It's a no brainer.

  

Cave One is finished! And we have a boss!

25.jan.2021 13:00 hrs

I started around 11 am this morning, and it took roughly 30 minutes to finish the layout of the cave and another 30 minutes to get the pixel art on the cave boss done. But the next 2 hours... The next 2 hours were pretty bad.

I threw everything I could at figuring out how I wanted to move this boss. Make him march around in a big circle? How about a figure 8? Make him pace back and forth? Make him zig-zag up and down, too? Ok, done. Sort of. Not really...

Ultimately, I kinda just wanted him to pace around in a random zig-zag. Walk straight, make a left, turn around, go back...? It just seemed like nothing really looked right. I looked at how bosses in other games moved and determined that this guy was going to be like Dodongo. But, again, it just wasn't working. It was too easy. Finally, I settled on making him slowly chase you.

It took me about 6 tries to finally defeat him, and I've determined that, if you can keep him from charging you while spamming the attack key, that's about the best way to do it.

  

The hammer thinks everything is a nail

25.jan.2021 19:00 hrs

I don't know how often it happens, but it's not every day that I break something only to find something else that seemed like it was working was actually broken. And then, the solution to THAT problem ends up being the solution to fixing both things. Confusing? Yup. Almost had another "broke down in tears," moment, but that's to be expected. The more complex this game becomes, the more difficult it becomes to balance the delicate ecosystem of hacks on hacks.

Now, buckle up, because this is kind of a long story.

Basically, I needed a way to keep track of the player's health when exiting from the overworld to get into cave_one. What I discovered was Global Variables, and as soon as I realized what they were, I knew exactly how I was going to use them. Only trouble is, they weren't working the way I thought.

Or, at least, I didn't think they were working how I thought... it's just that, I didn't realize the way I was tracking health was wrong.

Here, I'll explain: The health bar is a "heart" icon in a 16x16 tiled sprite. If you want to show 3 heart icons, you need the width of the tile to be 48. 3*16=48. So, in order to detrmine how many pixels wide the tile should be, you simply take the width of the heart sprite divided by player_maxHealth * player_health.

Let's say max health is 3 and the player currently has max health. So, 16/(3*3) = 48. Voila! Set the tile to 48 pixels wide and you see 3 hearts. Let's say you get hurt though, and lose one heart. So, 48/(3*2) = 32. We then set the health bar to 32 pixels wide and you only see 2 hearts. On down to 1, and then death. Conveniently, it even works for fractions. Lose 0.5 health off max, see 2 and a half hearts. Perfect. There's just one problem... What if you actually have more than 3 hearts?

That's where things were getting ugly. I purposely set player_maxHealth at 5, expecting to see 5 hearts so that I could test that the global variables were working, but I only saw 3 hearts. I tried again, and again, for several hours. Could it be the global variables don't actually work? Could it be that I'm just not doing it right? No matter what I changed, I would either get 3 hearts or nothing. I was going berzerk. And then, I finally figured it out.

If you, unlike me, are any good at math, you probably alread see what I did wrong. The problem is that dividing by 48 only works if your maximum health is 3 hearts because that represents 100% health. We were looking for percentages of maximum health here, not an absolute, hard number. If I were using an actual health "bar" and designing a game where the player_maxHealth number won't change, than 48 pixels would represent 100%. 100% could even be a bar going all the way across the screen. It wouldn't matter. But that's not what I was trying to accomplish.

At some point, I was also going to need a health upgrade for my character, anyway, so... For lack of a better term (and since Zelda is already where I'm working from as a point of reference) let's call it a heart container. So, I threw together a quick heart container and made it add 1 to player_maxHealth. Then I needed a way to change that pixel width on the fly, according to how many heart containers the player had. So, GlobalVariable(heart_container) = 3. Gain a new heart container? Add 1. Now, update the max health number; GlobalVariable(player_maxHealth) = GlobalVariable(heart_container). So, max health is also 3. Now, multiply the number of heart containers by 16 and you can figure out the rest.

The new formula for determining the length of the health bar looks like this: GlobalVariable(heart_container)*16/GlobalVariable(player_maxHealth)*GlobalVariable(player_health)

Just to test it out, let's assume you just defeated the first cave boss and grabbed the heart container they dropped, increasing your number of heart containers and max health to 4 (and picking up a heart container gives you max health to continue your journey). So, here we go:

heart_container = 3 + 1: 4. Therefore, using the above formula, 4*16/(4*4) = 64. The health tile should now be 64 pixels wide. And since 64 / 16 is 4, that means 4 hearts should be displayed at 100% health.

And that's it. That's how breaking the health system showed me that it was already broken from the start. As for the American health system... that's an entirely different story.

But here's the point of all this: now that I understand how to set and utilize global variables, I'm able to go beyond simply tracking the player's health across scenes. I've now set it up so that when the player exits the cave, the game can put the player back at the cave entrance on the overworld instead of putting them back at the main starting point. I also know if bosses have been defeated so that they stay dead if the player tries to re-enter the cave. And, lastly, I can put Jack back at the cave entrance when the player gets killed instead of sending him all the way back to the beginning of the game.

It may not sound like much, but these were all major steps toward building a persistent game world that would give the player the sense of an ongoing journey rather than just a bunch of random encounters. I haven't yet figured out how to "save" and "load" a game in progress, but rest assured; That's next on my list.

  

Randomizing enemy movement

26.jan.2021 12:56 hrs

By far, the hardest thing I've encountered in this figuring enemy AI.

I'd like it to feel random, but according to a pattern. Like, move up a random number, move down a random number, move left and right... I can move them back and forth, up and down, even in a circle if I want. But I just can't get them to wander around within a set limit. They either don't move at all or shoot off the screen at warp speed. This is infuriating.

I THINK I have a solution, but it requires levels of complication that I'm not able to process. Trying to break it down into a simple set of steps to follow and hoping for the best.

  

Randomizing enemy movement: UPDATE

26.jan.2021 14:55 hrs

*several hours later* Using timers and random spawn points has given me a lot more control over how I make enemies move, but they still kinda follow the same paths? It's not totally random, but at least it's something closer to giving them directions to follow. And, honestly, if I could just plug in simple instructions, like "Go up 10 pixels, down 5 pixels, left, right, repeat," I'd be so much closer to something I can work with. But I can't seem to figure out relative positions. I have to use exact coordinates on the X and Y axis to get them to move where I want them — which is frying my brain. It's a step in the right direction, at least.

  

How many legs?

27.jan.2021 14:55 hrs

Roomate: How come your spiders look like ants?

Me: What do you mean?

Roomate: Spiders have eight legs.

Me: Aww, shit.... Well, that's ok. My ants are wrong, too.

Roomate: How many legs do your ants have?

Me: ...four...

  

I </3 math

28.jan.2021

Let's say your screen area is 320 pixels wide x 240 pixels high, and you want your bad guys to pop up at random somewhere in there. So, your X coordinates are going to be 0 - 320 and your Y coordinates are going to be 0 - 240. But you've got walls you don't want them to spawn in, and you also want a margin for the player to enter the sceen...

Your character sprite is 32x32 pixels. Random(320) is any number between 0 and 320. So if you want room for them to enter the screen without an enemy immediately spawning on top of them, it's gonna look like this:

X = 32+Random(320-32)
Y = 32+Random(240-32)

This ensures the enemy can't spawn on any map position lower than 32 or any higher than 288. (Similar situation for the Y coord. 32 - 208).

All of that makes sense, right? Yeah, no problem...

...until you end up in the boonies with coords like -2056 and you have to keep reminding yourself that -1736 is GREATER than -2056 and you forget to add the negative symbol while trying to deduct 32 pixels, and this is the fifth screen you're calculating spawn points on...

And I was never any good at math, and I have a lousy attention span for remembering numbers, and I couldn't imagine coding this in 6502 assembler. NO FUCKING WAY

  

Poor, unfortunate souls

29.jan.2021 12:51 hrs

So, I'm building the spider cave, and thought, "You know what would be absolutely terrifying to find inside a giant spider cave? Pulsating cocoons of past adventurers, helplessly filled with venom, and just waiting to be eaten."

I mean, besides giant spiders, of course.

And then, I just riddled them everywhere, in the cave. All over the place.

  

Super unhappy to report

29.jan.2021 14:24 hrs

I've redesigned my spiders to make them about a billion times more terrifying (and gave them the correct number of legs, this time).

Imagine 4 of these on screen, as big as your character, coming after you.

I hate this game, now.

  

Brain Fry

29.jan.2021 21:41 hrs

Trying to pinpoint screen positions is really starting to fry my brain because I have to keep reminding myself that coordinates like -240 are greater than -480, and I have to add if I want to go down or right while subtracting to go left and up.

Like, I get the hang of it until I'm done mapping out what goes where and move on to the next screen. Then the madness begins again.

What I need is a method of mapping out relative positions, a way of getting the monsters to spawn in the room where Jack is currently standing. I think I have an idea of how to do that, I just need to experiment and see if I can get it to work. Will report progress later.

  

Enemy movement AI: revisited

30.jan.2021 2:05 hrs

My hunch paid off! I figured out a method for mapping out relative positions on the game map.

What I needed was a point at X 160, Y 120 - dead center. Of course, you can't just say, "Spawn creatures at 160x120," because that's an absolute position on the map. So how do I find the center of a particular 320x240 pixel area? I needed an object at the center of the screen that was already at the center of the screen, and would follow me around. In fact, I already had just the thing set up... The same method I was using to get the camera to snap from screen to screen!

I have an object named "camsprite" that jumps from space to space whenever Jack reaches a certain distance away from it. If you move Jack 160 pixels to the right or left (or 120 pixels up or down), the camsprite jumps 320 pixels (one whole screen distance) right or left (or 240 pixels along the Y access for the same effect up and down). The camera then lerps to that point, giving you a smooth movement, just like Zelda. (scroll up to older posts to read more about how I figured that out.)

So, basically, I can use that point as a relative position to spawn creatures at. Just tell it to spawn creatures at camsprite.X() and camsprite.Y() — plus or minus some random number of pixels so that everything isn't always clumped right in the middle.

And it works exceedingly well!

All I have to do is just plug in coordinates for where Jack is standing. For example, if Jack's X position is greater than 0 but less than 320, and Jack's Y position is greater than 0 but less than 240, drop 5 spiders at the camsprite XY position to put them in the room with him. Bingo!

There's just one last piece of business to take care of: enemy movement.

What I did was to set up a timer that picks a random number between 0 and 4 every second. Then, assign that number to a direction: 0=nothing. 1=up, 2=left, 3=right, 4=down. Every second, the creature moves 1 plus its current position in any random direction. It'll run left, then right, maybe stop, go up, stop again, go down, go left, etc. And each creature will do this. No more "synchronized dancing in circles." They skitter all over the place, completely independently.

I'm actually extremely proud of this one! It took me a good while to figure it out... I knew I was close to an answer, I just really needed to sit down and think about it!

  

Spider Cave is done

30.jan.2021 14:17 hrs

Annnd that's a wrap on the spider cave. Took me forever to get the movement pattern right so that the spider boss would circle back to the starting point before unleashing another attack, but it works. Death animations, sfx, etc., done. Only thing left is to add the prize to continue the plot of the game.

Until I got that pattern right, she'd slowly shuffle off to Buffalo and never return. Could take a minute, could take ten. Either way, you'd get to the boss chamber only to find it empty. "No boss" meant you'd be locked inside forever because you couldn't defeat her to unlock the trap doors.

How funny would that be, though? You get to the end of Metroid and there’s just a note from Mother Brain, “Got tired of waiting. Call back tomorrow.” All the aliens are like, “She’s not here. Don’t know what to tell you.”

Or Bowser is like, “You got the right castle this time, but we got hungry and ran out for dinner.”

Dr. Robotnic, tapping his watch, “World’s fastest hedgehog, huh? Took you long enough.”

  

World building

31.jan.2021

Today was a low-key day. I just wanted to chill, work on artwork, build more of the overworld and plot some elements that would be influential to plot. The world to the West now features an ocean with a river that drains to a lake that will be important for the endgame. I added spawn points for bad guys. Rearranged the map just slightly enough to force the player to explore a bit more. Originally, I had a beeline to the spider cave in the North for playtesting purposes, but now that the area is working as expected and the cave point has been properly coded, I made it more difficult to get to. Again, I want to encourage exploration and give players a world to see, so I'm spreading it out as far as possible and cutting off simple access points.

  

GRAPHICS!

1.feb.2021

Another low-key day. This whole time, I was using green tiles with squiggly lines to represent a treeline, but I decided to make them look more like tree tops for a jungle canopy. I made a boo-boo when I accidentally set the corners to be 32x32. I originally made a green tile with a rounded corner that was 16x16 to bookend the edges and round them off (you can see this in past screen shots). I used 16x16 so that I could place them next to each other in a 32x16 formation, but that won't be possible, now. What this means is that I had to spend some time rearranging things so that Jack and the enemy sprites would fit through passageways and other areas.

I could have (and should have) just made a new, 16x16 corner tile, but I liked the way these new tiles looked. They were so effective that I decided it was worth the extra effort.

I also spent some time making an animating a sprite to represent the wheel-house dungeon entrance. Instead of one large area made up of rooms, I think I'm going to make this a 3-level tower full of puzzles. Instead of fighting off bats and spiders, the player will have to solve some kind of puzzle. I don't know what, yet, but considering the end result is to get a machine running, I'm sure that will give me some clues about what to make. But that's for another day; I'll figure something out.

  

Quick rundown of the progress on Khaki Jack

- fix attack animation bug
- create weapon sprites: whip, machete(?), gun(?) bow & arrows(?)
- implement combat system
- create "attack" animations for Jack sprite
- finish construction on first cave: layout, tile design
- figure out how to make booby traps for the caves: darts, etc.
- create cave bosses, sprites, animations
- continue work on world map: location of other caves, items, weapons, etc.
- create a "bag" for Jack to hold items in inventory
- create explosives: dynamite
- magical items(?) Keys to unlock secrets?
- compose cave music
- sound fx: "hurt" sound (needs work), whipcrack, potion healing, enemy hurt cry, knife strike, explosive sound, heartbeat sound for low HP/near death
- create a title screen