Technical Dev Blog #2: Making Worlds
When originally designing our upcoming game, we planned to hand-build the world. This is a nice way to ensure the world is well-balanced, without having to spend *too long* testing (and indeed, building) a procedural generation system for our world.
The idea was pretty simple, mostly because it first came to us after several pints at the beer. I mean, pub.
The idea was that the world would be created as a huge image file – like, 16,000 pixels wide by a few hundred tall. Each colour would indicate a terrain type, and the alpha channel would indicate what type of ‘spawner’ would appear in each square.
For instance, a ‘forest’ spawner would trigger a forest most of the time (like, 90% of the time) with the type of forest (sparse, dense, pine, etc) being random based on settings we’d configure. A ‘rare mineral’ spawner would spawn some kind of rare mineral amongst some rocky outcrops.
Using this method, we could disburse these spawners about the world as we please, and every time a new game is created, part of this world would be dragged out of the file and used as the basis for this new game.
Nice theory, but there were a lot of problems associated with this that turned up as we began development. These included, but weren’t limited to:
- We’d need a sane set of dev tools to modify (or at least see) the “world” to edit it. Technically we could use an image editor, but editing alpha channels to add spawners is a bit insane.
- An image that huge without compression takes a lot of space, and if we wanted to load it using normal image loading libraries… it’d probably end up in video memory, at least temporarily… which is horribly inefficient.
- We’d need to load chunks of the file as required and spawn new stuff every time the world the player was in for this game increased in size in any way.
There were lots more reasons, but these were some of the main ones – and so we decided to bin our fancy idea and go with a “traditional” procedurally generated world.
This is presenting its own difficulties, but it sure is much more fun than we’d intended.
I’d initially shied away from full procedural generation because it was way beyond our experience level as programmers (and seeing some of the insane maths required to do what Notch does in 3D with Minecraft had me smiling politely and leaving the room). However, it turns out doing world generation (in 2D especially) actually has a couple of things going for it which make it easier than I’d expected.
The main one, and the one which is making it so much fun to do is this:
There is no ‘correct’ way to do it.
Want to generate lakes using complicated algorithms to deform multiple ellipses and ‘bleed’ them into each other? Go for it.
Want to do it instead by loading pre-set shapes? Go for it.
We’ve ended up doing it by picking a center point and carving ‘tendrils’ of water from random locations to the center. This makes odd shapes and can even give us small tributaries out to other lakes if we wanted.
But how you do it doesn’t matter – all that matters is that you like the shapes and formations you get in your world as a result.
I’m sure much more experienced world generation programmers would laugh at the simplicity of some of our techniques, but we don’t care – it’s just a lot of fun.