on Oct 20, 2010
Maybe the name of the project has given this away, but this game is going to be played on a hex grid. Hex grids are elegant, beautiful, and better-looking than standard square grids. The only downside to using a hex based gameboard is that the computer and I are both rubbish at thinking in hexes.
See, computer memory is really just a long list of addresses. You can think of it like a long street with houses in a row. At the start is house #1, and they go one after another all the way down to house #2,147,483,648 at the far end of the street. This is the structure of the world you work in. You can organize that information (conceptually, in your head) however you like. To can imagine them as a table of values by (say) treating it like a new row every 25 addresses. If you need a grid of data that’s (say) 25×25, then the item in row 2, column 2 is at position #27. Some simple math will let you treat that infinite line of addresses like a grid of points, but in the end your program is still dealing with a long, long list.
If I have a grid of 8×8 points, I can use them to make a 7×7 grid of squares. If that sounds confusing, (and I don’t blame you) then please enjoy the following visual aid, which was crafted by a small team of professional artists over the course of nine days, working in a variety of mediums, from calligraphy pens to watercolor:
Yes, prints are available.
This is really easy. (Making a grid, not the artwork.) It’s how my terrain project made a grid with millions of squares:
But how do you form this…
This is a really important step. I’m trying to figure out how to organize a hex grid in computer memory. The entire game will be constructed atop this grid, so if I do a lousy job it will make things harder for me later. If I decide to change it later, it will be like changing the foundation of your house after the thing has been built and you’ve moved in.
I finally decide to take a regular grid and play connect-the-dots with it like this:
I need to squash the grid vertically, making rows 33% shorter than they are wide. Then I make individual hexes 5 points tall, 3 points wide. This leaves a few unwanted points floating in the middle of the hex, which will go unused.
Actually, quite a few points will go unused. Over half. The upshot of this would be that I would waste a lot of memory storing data for points that I’m never going to use. It’s also going to be a bit strange making things move around a game board like this. I’ll have to work out a system for skipping points. This will also make it a bit odd to fill in the grid with data. If I load in some terrain I’ll have to map the grid positions into… uh…
No. No no no no. This is all wrong. This system could work, but it’s stupid and ungainly and there’s no reason to try and build a game on top of this mess. I need to think on this a bit more. And by “think” I mean “go play Civilization V”.
At some point in the game I start seeing the in-game hex grid differently.
Rather than all that nasty business with skipping points and squashing the grid, what if I just started with a normal, straight grid? And then shifted every other column of points downward by a half-unit? I just take this:
And render it like this:
As far as the computer is concerned, it’s a standard grid. But visually it’s… well, it’s a mangled grid. But if we connect the points right:
Note that while this looks like a hex grid, it’s actually not shaped like one internally. I’m rendering every other column of points as if they were a half grid space down. If I draw the grid without doing that shifting:
You see the world is really made of interlocking “house” shapes. This is what the game world looks like under the hood. When you move around the world, you’ll be moving around on this pattern of houses.
I realize that both of these techniques seem like oddly complex hacks. Maybe it’s not even clear why the second method is so much better than the first. I realize that any system to create a hex grid from a square grid of data is going to be a tricky one, but this second idea feels cleaner. Okay, the house thing is odd, but it feels like less of a hack than the first. Once I get the system in place, I’ll hopefully be able to ignore it. The point-skipping idea was the kind of thing that would come back to bite me again and again as the project wore on.
Well, we came all this way. Let’s feed the grid some elevation data and see how it looks:
Okay, the “elevation data” was just a couple of overlapping sine waves, but I like how this works so far.
Shamus Young is an old-school OpenGL programmer, author, and composer. He runs this site and if anything is broken you should probably blame him.