I’m only making a very basic game, and with a program that provides the base engine for you. But even so, that means hand-coding some pretty fundamental stuff, and it’s taught me that you can’t use the word ‘basic’ to describe anything you haven’t tried to code yet. I like to do stuff like The Hardest Logic Puzzle Ever in my spare time with a Google Docs spreadsheet (and xkcd’s The Hardest Logic Puzzle In The World in a text doc), but implimenting the most basic laws of game worlds is on a whole other level of complexity.
This bit of game logic, for instance:
Is impossible. I don’t mean hard, it’s just not the way algorithms work. You have to pretend it is, though, and the intricacies of that are what’s taken up most of my time.
The issue is that time progresses in discrete chunks in games, so just the word ‘when’ is problematic. Real life doesn’t really care if it’s not at exactly 1 second or 2 seconds that a man walks into a door, he just stops when he hits it. Code isn’t smooth, it has to re-examine and re-create the whole world sixty times a second, and there’s nothing in between these frames. Unless you want everything to move very slowly, some things are going to have to move more than one pixel at a time. That permits a nasty possibility: after 1 frame you haven’t hit anything, and after 2 you’ve already gone through it.
So collision logic fudges it one of two ways: the game either waits until you’ve already gone through something and pops you back out, or it looks ahead to see if you’re going to hit something and pretends you already have. The effect can be seemingly perfect, since these precautions are computed before the result is drawn on-screen, but it makes the underlying logic fiddlier than it ought to be.
Generally, though, it’s all fine so long as your character is a solid unchanging block.
That’s why a lot of 2D games have very compact, boxy characters: the game can treat them as a simple rectangle regardless of what animation they’re playing. Real people change shape much more dramatically when they run, jump and hit things. If you want a human-like character to dive headfirst into a wall – and I do! – you have to solve this insoluable problem for a thing that keeps instantaneously and dramatically changing size and shape.
I won’t get into why this is even more complicated, difficult and annoying than it sounds, but suffice it to say that the next time I fall through the ground in the latest FPS and plummet into the infinite grey limbo below, I won’t be thinking “Why can’t these idiots fix shit like this?”
I will be thinking “Why don’t these idiots account for shit like this?” though, because it only took me a few days of tinkering to realise a fundamental law of coding.
Then code what to do when it happens.
So early on, when I had so many collision bugs to fix that it seemed daunting, I spent some time on an “Oh fuck, I’m stuck” subroutine. It’s a little spiralling algorithm that searches with increasing desperation for a nearby space to teleport you to, should you somehow get stuck in solid matter. I know I’ll never solve all the minor or rare collision glitches that could happen, so I feel I should at least try to make sure they don’t break the game when they do.
Getting collision logic stable and robust was the hardest thing I’ve had to do so far, and the most intricate stuff I have planned for the game now seems trivial by comparison. I’m looking forward to the point when I’ve done enough of the coding that the question becomes “Is this fun?” rather than “Why doesn’t this fucking, fucking, fucking work?”