Landscape Optimization

There has been so much going on since the last post. The design document has received more work, detailing some changes to the backstory that is going to directly effect the overall structure of the game. Also, in the design document, we have detailed more recent game features that we are adding. Each major region of the game is going to have it’s own environmental game feature. For example, in the jungle, players will be able to obtain a grappling hook and swing through the trees. In the forest area the player will be able to gain access to a wing suit and glide through parts of that region. This last feature lead to some interesting observations and some decisions about the size of the game itself.

It was always our intention to make this a reasonably large open world. But, I hadn’t given much thought to just how big the main map would be. While testing the wing suit in it’s prototype project, I was able to glide over 0.7km (0.43m) in a single glide. This lead to the obvious question: Do we want to nerf this feature, or do we want to go big on the landscape? Having done Capuchin Capers as a series of reasonably large islands, and having dealt with the optimizations needed for performance, I knew we needed to test truly large landscapes before making this decision.

Landscapes are a big topic, no pun intended. I spent numerous days in Unreal Engine 5 Early Access 2 because I knew that Epic wanted to focus more on open worlds with UE5. After my testing, I have decided that we are going to stick with UE4 for this game. There are some great features in UE5 that directly impacts exactly how developers go about building open worlds, but I just can’t count on all of the performance issues with landscape actors in UE5 to be fixed at launch. A landscape in UE4 that would run at a very comfortable +120fps runs in the low 60’s to high 50’s in UE5. I know that Epic will get that sorted out, but we can’t put years of work into this project, all the while hoping that these issues will be resolved to a reasonable degree. World Partition, Lumen, Nanite, and MetaSounds are all great features, and I really wanted to take advantage of these. That is why I spent almost four days trying various approaches to be able to use UE5. But in terms of the workflow building landscapes, UE5 has a long way to go.

My experience with UE5 lead me back to UE4 and World Composition. I had watched the live-streams for W.C. and read the documentation for the system. Unfortunately, there isn’t much information for this system compared to other parts of the engine…it just doesn’t get used nearly as much as the ‘main’ areas of the engine. But, after spending several days testing and experimenting, I feel that I am getting my feet underneath me enough to be confident that we will be able to achieve our goals with W.C. There is a lot to learn about it, and some serious quarks to the whole thing that I spent way too much time fiddling with.

The first is making a truly large area without any seams between the landscapes, stored in the various levels in World Composition. I wanted a total map size of approximately 12km2, which would require a heightmap with a total size of 120992 (this was slightly off by a few pixels, but it didn’t really make a difference). I tried to create each landscape separately, in it’s own sub-level in W.C., but I kept running into a common problem. I was getting very small cracks between the individual landscapes. At first I thought it was due to the heightmaps having ever-so-slight differences in their color values along these seams. That was not the case. You can do any color corrections that you want, but it won’t get rid of those seams. Worse, you can’t use the sculpting tools to fix these seams because they are due to a separation of two different landscape objects. You can’t ‘paint’ across the boundaries, because in fact, the landscapes don’t share any boundaries. They just happen to sit next to one another. After watching the live-stream several times to try to get a hint of how to fix this, I noticed a really nice feature that is mentioned around the 47:36 time mark. Add Adjacent Landscape Level. Those are currently my favorite four words in the English language (that is why I highlighted them the way I did…I love those four words).

There are two approaches to using heightmaps in Unreal. The first is during landscape creation, via the ‘Import from File’ option. This approach will create the landscape based on the file chosen, generating presets for the number of components, section size, as well as the other settings for a landscape. This is nice if you have a single landscape in your level that isn’t larger than the limit for a landscape object. However, if you are attempting to create a map on the scale of an open world, this option won’t work. You inevitably get those seems between the landscapes.

Image 1: The first approach that you might take to creating a landscape using a heightmap.

The second approach to using a heightmap is to first create your landscape object, defining all of the various settings in advance, and creating a totally flat landscape (see Image 2 below). Then, once the landscape has already been created, you can load in a heightmap after-the-fact in the “Target Layers” rollout of the sculpting settings (see Image 3).

Image 2: Creating a landscape manually, by defining all of its parameters and pressing the create button. This results in a flat landscape with the dimensions that you defined in the rollout above.
Image 3: Using the orange ‘Heightmap’ button to load in a heightmap to be applied to your landscape.

Normally, when you are loading in a heightmap for a single landscape, there is little difference between the two techniques. With either technique, you can set your landscape’s component count, section size, etc. But no matter what you do, using these techniques alone, you can’t create a single landscape large enough to be used for an open world. That is where “Add Adjacent Landscape Level” finally comes into play and all of this makes more sense.

If you first define one of your landscape levels in W.C. via the ‘Create New’ menu in the W.C. tab and create your landscape tile using the “Create New” option, you can define your first landscape with all of the settings that you would need for a single tile in your open world map. In my case, that was the settings that you can see in Image 1 above. This is just one of nine tiles that make up my open world map, though, and I needed to add eight more to make the entire map. But make sure to keep in mind that I did not create that first tile via a heightmap. I predefined the landscape with the settings that I knew I wanted, and I created a flat landscape. Once that landscape was created, I used the “Add Adjacent Landscape Level” feature to create the other eight landscape tiles that I needed. You can see in the live-stream that when you use this feature, the landscape created does in fact go into it’s own level. But, it is sharing the vertices along the boundary with other landscapes created in this way. So, while each landscape is in it’s own level and benefits from all of the tools in W.C. that apply, the landscape objects themselves are seamless. You can sculpt or paint across the boundaries without issues.

That wraps up this rather long post, and in the next post I will discuss some of the issues that I ran into while working with W.C.’s LOD system that you can use. You can see the effects of that LOD system in the main image for this post (which I am also including below). Thanks for sticking with me on this post, and I hope that it helps you build the open world of your dreams!

Image 4: The open world test map. Some of the mountains in the background are over 3km away! The actual mountains are mesh proxies being used in World Compositions LOD system. More on that in the next post…that is called a teaser, and I am a jerk for doing that. But, that didn’t stop me, did it? 😀