Currently, I’m in the progress of adapting and changing the facialanimation system – no, I won’t talk about it. However, I still check out other parts of the game every now and then, and when I wanted to create a small preview video for our good friend Pappenheimer (who commented on this blog in the past, which makes him awesome (also, he is creating this really cool project called “Running food”, and now has a fascinating new online presence, about creating those games – sadly, only in german)), I noticed that on very low framerates, like the ones my computer gives me when I have Fraps running, my wonderful pathfinding didn’t seem to work.
Okay, thats not quite correct. The pathfinding worked well, it was just the routine that moved the entity along its path that had trouble. The entity would get near the first point on its route – the point where it had to turn the first time – and it would just stand there and rotate ad infinitum. Oh no! Thats no good! What would Pappenheimer think if he sees that?! He’d think the whole thing doesn’t work! Is no fun! Is just a laughable attempt of clueless beginners! No! That mustn’t be true! I won’t let it be true!
I closed Fraps, and I started coding. It was just me and the bug, it was going to be a battle of wits. It was either me, or the bug. “Hm…”, I said. Maybe, when the character gets close to the point, and continues moving, it overshoots, and thus never reaches the point! And thus, I added statements that would check if this was the case, and that had countermeasures against that behaviour.
The bug just smiles and nods. “Clever”, it said, and his face suddenly looks mean, “let’s see if you’ve defeated me already”.
And so, I ran the engine, started the program, let the code compile, and watched, as the menu faded in slowly. I clicked “Testsequences”, then “[sorry guys, can't tell 'ya, spoiler!]“. The three questions were answered quickly. The sequence started. Impatiently, I sat there, waiting for the small introduction – which is really very short, but it felt like it took forever. Hastily, I clicked on the first door, moving the character to the nearest spot on which the behaviour could be tested. There it was, another door, not too far away, a table standing in the characters way. He’d have to move around it. The perfect opportunity. I clicked, and watched in amazement, as the character moved closer and closer to the problematic spot. Closer… closer…
He stopped, and began to rotate. And rotate. And rotate. I didn’t look directly at his face this time, but the silent laugh I heard was unmistakably. The bug won this round. But why? Did my countermeasure not work? Or was it just not triggered? I had to check, so I put in a command that would exit the game immediatly when it was triggered. Sure, that was hardly elegant – a text or something would have worked just as well – but this method is easy and quickly implemented.
Ran the engine. Watched the code compile. Clicked the buttons, answered the questions, watched the introduction, moved the character to the spot. Watched him move closer.
The engine still ran. It didn’t quit. The character just happily rotated.
“Hmm…”, I said. “I wonder if maybe this is the problem…”.
The whole thing moves the character until he is pretty close to the spot, then he turns and moves to the next one. The problem was the “pretty-close”-thing. The positions were those of the nodes, and these are close to the floor. The character moving through the level is also standing on the floor, of course, but his “origin” – which is the point that is always given as his position – is in the middle of him, in other words, in a height of about 1 metre. Due to the relatively small distance in the check, this difference made a big difference and only gave the character a very small window around the point that he had to hit. This was impossible on medium to low framerates, so it’s good that I changed it – the target position now always gets lifted that metre.
And now it works like a charm. And they all lived happily ever after. Except for the bug, because he’s dead. DEAD, HAHAHA!