Blog 654: Terrain Up the Night (Part 1)

Now I’ve got some kind of actual gameplay mechanics in my game, which might offer some kind of challenge and interest, it’s high time I started to make proper levels in which to exercise them. Not, you know, some cuboids floating in an endless blue void.

Needless to say, nothing is ever as easy as it seems.

Terrain Up the Night

My background is in Warcraft III modding, and making levels for Warcraft III is totally unlike making levels for… well, anything else, really.

When you open a blank map in WC3, it gives you a big platter of solid ground to start with. You can raise and lower it smoothly, or you can inject sheer, impassable cliffs and put ramps up and down them, and you can paint different surfaces onto that platter.

It might not sound like much but that’s actually a hell of a springboard. Before you’ve even added decorations, before forests and rocks and houses and characters, you still have some raw material from which to begin chiselling out your ideas, blocking out regions before refining them into real places.

Unity, of course, begins with a formless void. Empty, pure, yes — but not particularly inspiring.

Insert game here.

Insert game here.

My ideal of level design harks back to the likes of Sonic 3D, whose level spaces were grids of tiles, with each tile roughly the right size for a single character to stand on. I want everything to be constructed to scale, so with the Delta mech being the equivalent of “one human character” from my camera distance, I have a level grid with each tile of side 2 in Unity. (In Milkshape it’s 20 — although the Delta is actually around 200 in Milkshape, Milkshape breaks down the further you zoom out so I’m working small and having Unity scale on import).

But Unity’s scene space is empty; there is no matter from which to carve this mythical grid anyway.

To fill the abyss, Unity provides a terrain object, which is a traditional heightmap system with a few bells and whistles like automatic decoration systems on top. The thing is, I don’t really get on well with heightmaps. This Wreckage and Project Y4, you may have noticed, are basically flat apart from the sheer cliff walls that bound their gameplay spaces. In my real games I want to be a little bit lumpier than that, but I really need big cliffs — which are awful in pure heightmap systems, where there isn’t enough geometry to go between two contrasting nodes and you get ugly stretching.

Luckily, the terrain object's lowest possible resolution is about the right size for me. Shame it's still a heightmap.

Luckily, the terrain object’s lowest possible resolution is about the right size for me. Shame it’s still a heightmap.

Inevitably, I had to begin considering how to write my own terrain system, one that fulfilled all my needs directly. Unity doesn’t want to do sheer walls, fair enough — don’t fight the engine trying to force it to be something that it is not. I kind of want the smoothness of a heightmap system, but I really want to get the sheer cliffs of WC3 into the mix.

The approach that kept coming back to me was voxels, but I don’t really want them either. Although I’m going for a grungy low-poly aesthetic, voxels are too blockular for late-90s pseudo-realism. Voxels are a particular look that works in its own right, but it’s not quite what I am aiming for. I want to have slopes as well as walls. Aargh!

So I started off experimenting with a customised heightmap system, trying to marry the power of voxels with the power of a heightmap. Instead of using one pixel for one vertex, I’d use four vertices and snap neighbouring tile edges together if they were close enough in height, or introduce a side wall if they were far apart. Surely this would give me the perfect middle ground that only reinventing one of gaming’s oldest wheels could give?

It's all plain sailing until you try to join the dots.

It’s all plain sailing until you try to join the dots.

Nope, it really didn’t work.

That extra step of using four vertices for each tile ended up with nasty snapping artefacts — since the intersection of four tiles has to be considered for snapping a single point, the lowest and highest tiles could be far enough apart to be considered candidates for a sheer wall while the two middle-height tiles could be close enough to think they should all be snapped. Paradox! Disaster!

Writing it into a Milkshape file didn’t exactly scratch any itches either. Importing to a model editor to export to another format to import into a game engine is no workflow, especially when raw terrain is so very fundamental to the sort of level I expect to be designing. Fiddling with a heightmap and running a command-line application on it is never going to match the in-place editing I used to get in Warcraft.

Nice try, hotshot.

Nice try, hotshot.

So, it seems like I need voxels after all, and I need to do them directly in Unity. Voxels, of course, provide sheer walls by their very nature, without having to force cliffs in against the flow of a heightmap. Sheer walls that come with too-hard edges in other directions too, sure, but I started to figure that, once I had the basics in place, I might be able to bolster the pure voxels with ramps, corners, half-blocks and more — enough extra fiddly geometry that nobody will know it’s a voxel engine in the end.

I mean, it’s not like I even considered using somebody else’s voxel engine. I don’t need an endlessly procedurally generated lattice through which to tunnel — I just need a convenient way to hand-craft reasonably-sized platters of landscape, in situ.

Building your own voxel terrain editor is, of course, not an easy task, so we’ll explore that in part 2…

Advertisements

And you tell me...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s