Dirty Hacks

Posted by marbs on June 24, 2013, 5:31 p.m.

Sometimes you just have to get code working, regardless of how pretty it is. This is especially true for game developers, since you generally want a playable prototype as fast as possible.

I find this quite difficult sometimes. My progress gets bogged down by planning for the future, by writing clean and modular code, or by finding the optimal solution for everything.

Perhaps my engineering degree created this desire for perfection? I don't think so. Code written by my lecturers was almost always very messy, with sloppy indentation and inconsistent braces. (At least it wasn't as bad those ancient hieroglyphics they call handwriting.)

So do I write perfect code? Definitely not! Looking back at code I wrote months ago, weeks ago, or sometimes even just seconds ago, I spot things I would do differently. Why is this? That answer could take up a whole other blog post.

What I want to show you is this level editor I've been working on:

Above is a cubic bezier curve.

The black shapes can be moved to manipulate the curve. The squares indicate end points (where the terrain begins and ends), while the circles represent control nodes (used to manipulate the shape of the curve.)

It was surprisingly easy to implement, taking only a few hours. Feeling confident, I decided to add circular arcs as well. After all, surely arcs would be super easy in comparison?

Above is a circular arc. It turned out to be terrifically hard to implement, and took, on and off, about three days to get working.

I found it very irritating because, at the outset, it seemed like such a simple thing to do! The user places three points; two squares and one circle; then the arc then just has to pass from one square, through the circle, to the other square. For any three given points there exists a circle that passes through, so it is just a matter of determining this circle, and taking only a section of it - the arc.

The first bit I could do - determining the circle - that was a simple wikipedia job. It was the second part that stumped me.

I managed to isolate the problem down to a couple of things. Part of the it was this: my algorithm incorrectly calculated the angle that passes from one square, through the circle, to the other square.

In the above image, the correct solution is the yellow angle. However, my calculation would always return the shortest angle, so it never worked for a reflex arc. I spent a while trying to find a mathematical solution to this, but hours passed and no progress was made.

Through experimentation, I found that by manually adjusting a couple of boolean parameters of the arc generation code I could always create the correct arc! The parameters controlled a couple of things: whether to flip the arc direction, and whether to subtract its angle from 360 degrees.

And so I arrived at my solution: brute force!

Given that one combination of the aforementioned two boolean parameters always led to the solution, this meant that only 4 possible combinations exist. So I stuck the arc generation code inside a loop which tries all 4 combinations and returns only the correct one. It works flawlessly!

Is this solution sub-optimal and terribly ugly? Yes; but that's not important! What really matters is now I can move on to making it playable, and find out whether the game is fun.

For similar tales, read the Gamasutra article on Dirty Game Development Tricks. My favourite one of those is where the programmer exploits a buffer overflow to patch his own game. Oh, and also the one where they store audio data within a 3D model.

What dirty hacks and programming sins have you committed in order to get things done?

Comments

Acid 10 years, 10 months ago

I didn't make it, but there's this website that I go to all of the time that uses a TON of dirty hacks to run. I believe they're working on fixing it, but it seems like there's still a ton of grimy brute forces there.

ludamad 10 years, 10 months ago
Acid 10 years, 10 months ago

Kenon's input would be perfect for this blog.