Questions about RTS game cliff terrain

I was rummaging through the forums.

And then I started making attempts

package com.mygame;

import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.system.AppSettings;
import com.jme3.util.BufferUtils;

public class SimpleGridApp extends SimpleApplication {

    public static void main(String[] args) {
        SimpleGridApp app = new SimpleGridApp();
        AppSettings setting = new AppSettings(true);
        setting.setWindowSize(1920, 1080);   

    public void simpleInitApp() {
        int width = 100;
        int height = 100;
        float spacing = 1.0f;

        // Define vertices for the grid 
        float[] vertices = new float[width * height * 3];
        for (int x = 0; x < width; x++) {
            for (int z = 0; z < height; z++) {
                vertices[(x * height + z) * 3] = x * spacing;
                vertices[(x * height + z) * 3 + 1] = 2;
                vertices[(x * height + z) * 3 + 2] = z * spacing;

        // Define indices to create triangles
        int[] indices = new int[(width - 1) * (height - 1) * 6];
        int idx = 0;
        for (int x = 0; x < width - 1; x++) {
            for (int z = 0; z < height - 1; z++) {
                int topLeft = x * height + z;
                int topRight = topLeft + 1;
                int bottomLeft = (x + 1) * height + z;
                int bottomRight = bottomLeft + 1;

                // First triangle 第一个三角形
                indices[idx++] = topLeft;
                indices[idx++] = bottomLeft;
                indices[idx++] = topRight;

                // Second triangle 第二个三角形
                indices[idx++] = topRight;
                indices[idx++] = bottomLeft;
                indices[idx++] = bottomRight;
        // Create a Mesh
        Mesh mesh = new Mesh();
        mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        mesh.setBuffer(Type.Index, 3, BufferUtils.createIntBuffer(indices));

        // Create a Geometry to display the mesh
        Geometry gridGeometry = new Geometry("Grid", mesh);

        // Create a material and set its color
        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        material.setColor("Color", ColorRGBA.Gray);

        // Attach the gridGeometry to the rootNode

This code I used to generate the grid。

The part I currently can’t grasp is how I should apply tiles to the cliff sections.

How was this part realised? If anyone is interested feel free to leave a comment!
I’m still trying this part out there is very little information in the web maybe I’m using keywords by mistake, if you have seen something similar please recommend it to me thank you very much!

In halo wars the used a full displacement vectors (vector3f) for the terrain data instead of a heightmap based terrain.

In the earlier days i think they just placed a mesh over the terrain


It seemed to me that it would also be a good。
I haven’t played the game yet, I’m looking for Halo Wars gameplay videos to watch。

OpenRTS is based on Starcraft 1 & 2, in which cliffs are standard height objects. So a tile becomes a cliff instead of a flat ground, depending on the altitude of its four corners (nodes). There are only a few altitudes and they are integers. In OpenRTS and Starcraft, altitude can be 0, 1, 2 or 3. In Starcraft2 there was an additional altitude -1 which was used to place infinite cliffs under the ground.

If only one corner of a tile is at a higher altitude, the tile become a salient cliff model.
If two non-opposite corners are at a higher altitude,tthe tile become a strait cliff model.
If three corner are, the tile become a concave cliff model.

The editor should not allow two opposite corners to be at a higher altitude or you should have a special cliff model for that (Starcraft 1&2 does not support that)

In Open RTS and Startcraft 2 (not the first one), another system is used to change the height of the flat terrain. Please understand that these two systems are independent and a flat terrain at altitude 0 raised above another flat terrain at altitude 1 won’t change the terrain altitude. And of course, the nodes around a cliff element can’t be raised at all because the cliffs model are fixed to their altitude so they can connect nicely with each other.


Thank you for your reply and it’s good to see you’re still in the community, sorry for the somewhat late reply, I’m trying out what you’ve said I’m now gradually getting to understand how this part of the content is made which is thanks to your explanation thank you very much!

The only thing I don’t understand right now is how am I going to place the cliffs on the map? Do I go through each point on the map to determine where the cliff model should be placed?

A tile is the square between four nodes/corners. The cliffs are 3D models that occupy the entire tile, and their height is what you decide it is (in Starcraft 1&2 and OpenRTS, each level of altitude equals 2 times the width of a tile).

So you need to have at least 3 models for a cliff set.

  • One for a convex corner, let’s call in “outer cliff”, ie. come from the east, turn 90° and goes to the north, the upper part being at the north east
  • One for a concave corner, the “inner cliff”, ie. come from the east and go to the north, but the upper part is the south west.
  • one for a “straight cliff”, ie. come from the south and goes to the north.

You need of course to rotate these models accordingly to the situation.

In addition to these models, you can variants for each to choose randomly or specifically in the editor, and you can also have models for a sequence of 3 straights cliffs in a row, to have bigger objects like a big door, a large rock, or a model for a inner/outer/inner sequence that creates a nice wall instead of the basic angular shape. All of this is present in Starcraft 1&2 but not in OpenRTS)

One last thing is the connexion between the terrain and the cliff. This one is tricky. The cliff model occupy the whole square tile, but for natural biomes you need to have at least a piece of the same surrounding terrin in this tile too to avoid a straitgh line between cliff tiles and terrain tiles.

In Starcraft 1 you had tile of terrain and tiles of cliff, and the cliff models had a little piece of terrain on it, textured in the same way. This was a limitation because you couldn’t paint the terrain near the cliffs and you would need to choose between a lot of materials for your cliff so it merge correctly with all available terrains, both on the upper and lower sides.

In OpenRTS, the tiles with cliffs also has a square of terrain on the lower part and the upper part, which is a special mesh that is added to the terrain mesh and connect vertex per vertex to the cliff element. This allow to paint the terrain to the very edge of it.

In Starcraft 2, the same thing happen on the lower part of the cliff tile, but they have opted for a better solution on the upper part of natural biomes cliffs. A piece of terrain is added on the edge and the material become gradually transparent over the cliff model. This create a nice merge between the grass and the mostly mineral model of the cliff and give the impression that some grass is fading over the edge. This feature is not present in OpenRTS.

1 Like