Custom Terrain Generation Using Heightmaps

In one of my current game projects, I hit a motivation-wall almost a year ago when I realized I would have to manually construct terrain maps of considerable size.

To be a bit more specific on the terrain itself, I am not using Roblox’s terrain. Instead, I am constructing worlds using blocks with a 4x4 base and a height of 3. (That way, the slope blocks have a hypotenuse of 5 studs!) There are also several biomes that I am using for these worlds. As you can see, building such worlds manually would be quite tedious.

However, the last few days I have been thinking about using two images in order to more quickly design these worlds, and then using code to actually import them into Roblox. Below are two sample images that have been blown up in size. Each pixel represents one 4x4 block. In the heightmap (the black and white one, as you may guess), pure black is sea level and lighter colors are higher elevations. The differences in shade would be much more subtle for my actual map designs, but I went with higher contrast for the sample for easy viewing. In the biome map, blue is water, green is grass, and yellow is sand. Again, I’d have a wider range of colors for actual map designs, incorporating more biomes, but I went with simplicity for the sample.

SampleHeightMapBlownUp SampleBiomeMapBlownUp

My maps will also eventually have slopes between different levels of elevation as well as occasional oblique corners rather than just hard, 90-degree corners. But I will deal with those issues later. For now, I’m just focused on turning images into Roblox parts.

Now for the code part.

It doesn’t look like Roblox Lua has any way to read pixels directly from an image. Thus, I would have to write an external program to convert images into something Roblox Lua can deal with. I can certainly write a Java program to do this. But my question to you is, what format should this encoded data take and how should I then import the data into Roblox?

First, I decided it would probably be easiest if, for the heightmap, 0 is sea level, 1 is one block high, 2 is two blocks high, etc. and for the biome map, use integers to represent each biome, i.e. 0 as water, 1 as grass, 2 as sand. I could then write this data to a text file and copypaste that into Lua. The rate at which I would be making maps would probably not be high enough for the copypasting to bug me that much, but if there’s a nice work-around, I’d be up for trying it. I think I would then just encode this data as a 2D array in JSON and let Lua decode that JSON. Turning that 2D array into parts from there shouldn’t be much of a problem.

What do you think?

4 Likes

For data transfer I’d just use the pixel parser java program and throw on some local server hosting and write a quickie plugin to import it json and build the map. I used a local java server for my image rendering program and have the source code included if you are interested. M̶i̶n̶i̶m̶a̶p̶ ̶C̶r̶e̶a̶t̶o̶r̶ ̶[̶R̶o̶R̶e̶n̶d̶e̶r̶]̶ DEPRECATED Ignore the fact that when I wrote this I completely forgot that java is written with camel case, the entire thing is pretty messy but it works : )

1 Like

You may be interested in the .ppm (color) and .pgm (grayscale) image formats. They are as simple as a image formats get, and almost all image manipulators support them. After saving an image in this format, change it to an ascii text file. I’ll look something like this:
(sample for letter J taken from wikipedia)

P1
6 10
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 1 0
1 0 0 0 1 0
0 1 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Which can easily be transformed into a table of tables of numbers and hardcoded as a table in a script, or transferred from an external server every server load.

1 Like

The .ppm and .pgm file formats seem pretty neat. But I think I will stick to writing a Java program to convert .png files simply so that 1) I don’t have to install a Paint(dot)NET plugin and 2) I can teach myself image IO in Java and possibly work on my Java optimization skills.

I currently use a another method, it doesnt require coding at all.

All you will need is Blender, Basically sculpt your terrain in blender and export it as OBJ
This isnt the Typical Import as a mesh part due to unstable Collisions.

You will have to get one of those old plugins that supported OBJ import way before this was official, basically a plugin that represents each polygon or your Blender terrain mesh as triangle parts in studio.

If your interested in this method message me so i can explain further.

As I had said, my terrain here isn’t any sort of smooth/realistic terrain. Instead it is meant to be blocky, constructed out of 4x4x3 blocks. It’s for a game that is supposed to look rather isometric. Thus, using a heightmap in which each pixel represents a block would work well as a solution.