Creating a 3D world for an RPG

Started by
8 comments, last by Outliner 6 years, 5 months ago

I'm trying to create a simple RPG in the classic Final Fantasy style where the player wanders around a world having menu-based encounters. I want the world to be 3D, but I'm not aiming at anything like Skyrim with its realistic-looking world. I don't even want to try to fool the players into thinking I lovingly hand-crafted meshes for each area. On the contrary, I want meshes that are simple and procedurally generated so I can design the world in broad terms without having to model every detail of the terrain by hand. To be clear, the world is not going to be procedurally generated; that will be hand-crafted along the the encounters and story of the game. What needs to be procedurally generated are the meshes that are rendered to represent the world to the player, because the resources are not available to generate a whole world of meshes by hand.

My only real requirements for the world are the things that would be expected of the usual RPG. It should have vertical cliffs to block the player's movement, along with cave entrances in some of the cliffs. There's no need actually carve a cave into the cliff mesh; it can simply be a symbolic entrance that takes the player to another scene. The game should also have impassible forests which are like cliffs but rendered as a solid wall of trees. It should have deserts and swamps to cause the player to move more slowly, and roads to cause the player to move more quickly. It should have buildings to trigger menu-driven events, but the buildings can be as simple as cubes with tasteful textures. None of these elements needs to be rendered in great detail, but it is important that there be enough variety to allow the player to recognize a place that has been seen before.

I'm prepared to accept that the world may need to be created on a regular grid. Of the many tutorials that I have looked at, the Catlike Coding tutorial for doing Hex Maps in Unity is by far the best. It goes from the simplest of hex grids all the way to creating worlds with mountains, roads, and rivers. I cannot express how helpful it has been, though it is not a perfect fit for my needs. For one thing, there are no hexes in the design document of my game. It seems that the whole project could be simplified by using squares instead of hexes, but either way I'd want to try to minimize the appearance of the grid. It occurs to me that I might create a height map within each square to allow for detailed hills and valleys as opposed to the rigidly defined plateaus of the tutorial's hex map. Even so, it's hard to disguise the grid nature of the world, and it's hard to give a place distinctive look when it is confined to a rigid grid.

I love the idea of spline-based roads and rivers, but unfortunately it seems difficult to combine them into a height map terrain. It seems that 3D spline roads work best when they are somehow floating in space, akin to the F-Zero games. Here is a Youtube tutorial going into detail on how to create such floating spline roads:

" rel="external">Unite 2015 - A coder's guide to spline-based procedural geometry.  Here is an article I found discussing the combination of vector-based features with height map terrain: Real-time rendering and editing of vector-based terrains. The title is fascinating because it suggests that the article would be excellent for my needs. Another such evocative title is: Automating the Construction of Large-Scale Virtual Worlds. Unfortunately I don't have the full text of that one. Looking deeper into this, it seems that putting spline roads onto height map terrain is actually one of the great problems for the ages. All the solutions I can find are quite elaborate, and this is intended to be a simple game, not a display of technical wizardry.

The difficulty of using spline roads on height map terrain suggests the possibility of using spline roads without height maps. Nothing in the design document particularly requires hills, though it's hard to imagine how places in the game world can have distinctive looks if the whole world is perfectly horizontal.

I have also considered doing an entirely voxel-based world akin to Minecraft. It might use Marching Cubes to smooth off the corners. That would be an entirely different can of worms.

There are so many options available and all of them seem either difficult or low-quality. On top of all the rest, in order to have a large world I have to consider how to divide the world into chunks.

It would be wonderful if someone who knows how to make games would point me in the right direction. This is not my first 3D game, but I have never attempted anything on this scale before. I'm prepared to put effort into this game, but I don't want to waste effort doing it the hard way when all my requirements are so modest. Up to now I've been using Unity for my attempts, so Unity-based recommendations are especially welcome.

Advertisement

I have worked on many games that have used Hex-Fields, Splines and Traditional Terrain that technologies have all there advantages but are to be used for certain purpose situation based. I used (and have seen to be used) Hex-Maps as some kind of game board in a turn based creature evolution game with different levels and consistancy. I took a Minecraft approach to chunk pilars of those hexagon tokens together to build caves, ocean and of course lava terrain along with hills of rock and grass that was generated by hand but modified during gameplay (as part of the gameplay when someone played a Meteor card for example) and some RPGs use it like Daedalic's Blackguards that looks quite beautiful. The benefits are that you have some grid based terrain without that clunky look some quadric grid based games have when you design the surrounding environment well so that it fits into a players eye.

Spline based terrein is something you will mostly use for games where roads matter, like a driving simulator. I took part on several games of that genre that's designers dragged roads into an empty scene in Unity and let the generator define what kind of roads they are (lane width and count as same as junctions) and what and how the surrounding terrain looks like. The terrain then was generated as procedural mesh in order to surround the road to keep the player from looking into the blank empty nothing. The designers than had to place vegetation and other assets by hand.

Last but not least, traditional heightmap terrain. I used this on a medival city building game where the map was fully handcrafted by drawing a heightmap and place water, trees, rocks and other stuff on it. This is mostly the case when you need a fixed terrain that has some more detail except the spline based roads. You do not need to do it by hand but could use some tools like Terragen or World Machine to let someone generate the terrain for you and just import it into your game then.

 

Know the other topic about streaming your world. Doing so is a must have technic in larger open world games away from the traditional map based games because you need to immediatly load/discard areas of your terrain and will potentially have LODs to make it perform smooth. You normally will chunk your world into an ammount of quads that are as large as the most significant viewing distance so one wouldnt be able to see the edge of the world and mountains popping in and as small as possible to keep performance on the go. I have already seen some systems that utilize quad trees storing several kinds of LODs for a terrain cell so you could immediatly swap your LOD level when player comes closer. All you need is a distance based system that will automatically load new cells in the background to display and discards obsolete cells when leaved so this shouldnt be a problem. When you have large terrains you might need to edit/store your terrain as a whole one and chunk it into cells and LODs on post processing your assets before shipping.

 

When I would be in this situation, I would start going with a heightmap of my terrain so that you have a good base terrain that is as you wished it to be and would then make some visual editor that has a capable set of rules and categories for your in-place assets like trees, rocks, cliffs and spline roads/rivers. Place roads/rivers on the terrain and let the road generator modify your heightmap from certain rules so that you will get a visual representation (of path digging into the terrain or just by a different texture) just by testing the points that are in the area of your spline road. You will finally still need to place other assets by hand but have some kind of basic description

  • Type/Category
  • Bounds
  • Orientation
  • Special Conditions

and let a generator go by defined rules for example to make a rock that is of exact these description creating the Mesh, its LODs and choose a matching texture based on the environmental rules (Swamps may have dark gray rocks with some moss on them while Deserts have terracotta colored rocks with cracks). Place in your whole terrain those abstract entities and push the generate button to let your generator do the work.

Maybe I will steal your idea to implement it into my own game engine tools while I think it could be a potential good one :D just for the case that artists are rare to find for hobby projects these days ;)

19 hours ago, Shaarigan said:

Place roads/rivers on the terrain and let the road generator modify your heightmap from certain rules so that you will get a visual representation (of path digging into the terrain or just by a different texture) just by testing the points that are in the area of your spline road.

If we're not generating geometry for the roads/rivers, then there's little use for the spline. The chief advantage of having a spline is that we can trace its path creating vertices and edges. If all we are doing is rasterizing the spline onto the height map grid, then we can simply define the road/river as a raster image layer on top of the height map. That gives even more control over the path of the road/river than a spline would.

There are at least two big issues with this approach. For one, raster images always suffer from pixelation, and there's no apparent way to prevent the player from seeing the pixelation along the edges of the road/river except using an awfully high resolution raster. For another, when a road is represented by just another texture on the height map, it never really looks right. The texture doesn't align itself with the direction of the road in the way the details of a real road always do. Splat map roads always look like splat map roads, and I had very much hoped to do better with my procedural meshes

A smaller issue is the question of doing cliffs. Vertical slopes are impossible in a standard height map, and very steep slopes always look shabby. I have some ideas for how to overcome this issue, but they still suffer from the resolution problem that always plagues a height map. The difficulty of doing cliffs in a height map was one of the issues that drove me to consider grid-based approaches.

19 hours ago, Shaarigan said:

You will finally still need to place other assets by hand.

I have been considering using an algorithm to randomly place things like rocks and trees, so the world designer only needs to define the density of these assets and doesn't need to place them individually. Of course there would be rules to prevent randomly placed assets from appearing in roads or rivers.

20 hours ago, Shaarigan said:

Maybe I will steal your idea to implement it into my own game engine tools.

If you manage to solve the difficulties, please share your solutions.

3 hours ago, Outliner said:

from seeing the pixelation along the edges of the road/river

As I mentioned, I would just start using a heightmap and put a road/river spline on it to tell the road generator where my roads/rivers are. (This could also be usefull for AI pathfinding). At the time the road generator comes into play (maybe I wrote it a way you misunderstanded that) you will already have the terrain mesh

triangulate4.gif

so the road generator is capable to modify those vertices in order to form a proper road/river without the rasterization problem. Anyways your terrain generator needs to work on the heightmap generated output otherwise you will always have some rasterization artifacts in your mesh. You cannot (you can but either it looks awfull or data outcome is very high) grab your heightmap as-is and expect AAA terrain. Even when your resolution is at a good size on import, your terrain needs to be optimized to lower the poly count on flat/avarage parts while keeping detail on cliffs and mountains

SNAGHTMLf7177%5B3%5D.png

So the resolution/rasterization artifact question is non-sense here. I agree when going for something like Unity 3D's terrain system you will have pixel edges but only because Unity's terrain assets are fully in-game modifyable so you can change each "pixel" mapped cells texture, brush and height.

Cliffs should be also handled by the terrain generator when needed so you might set/mark certain area as a cliff generated area that will be post processed. Those informations might be included into your heightmap when using 16 or 32 bit images or from outside resources like a configuration file.

3 hours ago, Outliner said:

I have been considering using an algorithm to randomly place things like rocks and trees, so the world designer only needs to define the density of these assets and doesn't need to place them individually. Of course there would be rules to prevent randomly placed assets from appearing in roads or rivers.

I cant imagine that this will have the same quality as individually set assets except for large groups of objects like a forest. Otherwise I would always prefer setting things by hand so you know where your rocks are and that the chest you placed there is always reachable and partially hidden so it isnt placed in the middle of a meadow but also not inside the rock

15 minutes ago, Shaarigan said:

You will already have the terrain mesh so the road generator is capable to modify those vertices in order to form a proper road/river.

That sounds fascinating. Can you provide some references to resources that explain what you mean? It sounds like you're suggesting we re-position the existing vertices to form the road/river, but I'm guessing that you really mean deleting the vertices along the path of the road/river and then creating the road/river geometry from the spline, then somehow connecting the road/river geometry to the terrain. It's hard to imagine how we could re-align a grid to follow a spline otherwise. It may depend on what you mean by "a proper road/river."

35 minutes ago, Shaarigan said:

So the resolution/rasterization artifact question is non-sense here.

That is amazing. I would love to know more details about how we've eliminated all raster resolution artifacts. I see that the terrain generator does some "work" on the height map mesh to eliminate the problem, but I would love to read some sort of reference about the work. Does the algorithm have a name? Discovering how this is done seems like it would solve problems that I've been researching for a long time. I imagine that it somehow moves the vertices around to smooth things out. Is that on the right track?

On the other hand, do you just mean that resolution artifacts are eliminated because optimizing the mesh to have fewer triangles on flat areas means that the raster can freely have enormous resolution without creating excessive triangles, and that enormous resolution would eliminate resolution artifacts?

22 minutes ago, Shaarigan said:

Cliffs should be also handled by the terrain generator when needed so you might set/mark certain area as a cliff generated area that will be post processed.

It is quite a challenge to integrate cliffs into a height map, especially if the cliffs are allowed to be an arbitrary spline. It would be interesting to know what you mean by "set/mark" exactly. Are you thinking of spline cliffs? Or are you thinking more like marking certain pixels on the raster? When you say "post processed" that makes it sound like the cliffs are added to the mesh at a step that is later than some earlier processing. What should come before the cliffs?

I will tackle the field from behind :)

1 hour ago, Shaarigan said:

I would just start using a heightmap

So you are going to create your heightmap based mesh first before doing any post processing. I would then, however, inject some information into the post-heightmap-mesh-processing step to make additional adjustments like adding/creating cliffs for certain rulings. When marking pixels in your heightmap as a cliff edge, you are able to define a path that follows those "points" and making a spline from points should not be the problem.

We used the same technic to create a network of roads for our driving simulation game by just setting some path points and let the generator do the trick for us

maxresdefault.jpg

You see that the spline is made from just a few points defining the roads segmentation and connection points (this is just a sample to illustrate how our system looked like similarly)

Now roads/rivers (and cliffs) could be processed by certain rules from the terrain generator before optimizing your mesh. Your mesh should now look like the first image in my last post, a bunch of grid based vertices where a spline generated road would for example look like

1935-schermata+07-2456125+alle+11.58.09.

All you have to do now (or your terrain generator) is to change (and potential add if needed) your grid based vertices to look like this spline road. I do not know at this time how the adding/modifying method performs against cutting and stitching your terrain and spline together, this may be implementation based.

Your terrain generator can also add new vertices by splitting triangle quads up into more triangles to smooth your terrain a little more if needed so it wont look blocky as I meant with the rasterization issue.

However, your last step should always be to optimize the terrain by merging certain vertices that are in height compare below certain threshold but keep vertices at other areas that are higher in detail so it has fewer polys as seen in the second image of my last post.

This is all information I could provide in general without going too deep into that topic. Terrain generation is an interesting area so you might read further about it for example at this site providing a lot of papers about terrain generation and optimization alogrithms ;)

6 hours ago, Shaarigan said:

All you have to do now (or your terrain generator) is to change (and potential add if needed) your grid based vertices to look like this spline road.

That sounds great. I would love to have a link to a guide or paper describing how to do that, or perhaps the name of an algorithm, or some keyword that would help google find such things for me. Some sort of lead to help toward further research would be excellent. If this is a technique that people are using then I would hate to have to re-invent the technique just because I couldn't find the algorithm that they are using.

Alternatively, are you recommending that we should invent this algorithm because you know of no algorithm for doing this? If there is no such technique currently in use, then my attempts to google for it are wasted.

6 hours ago, Shaarigan said:

Your terrain generator can also add new vertices by splitting triangle quads up into more triangles to smooth your terrain a little more if needed so it wont look blocky as I meant with the rasterization issue.

So we can avoid resolution artifacts by increasing the resolution in specific areas as needed, such as by subdividing grid cells and smoothing inside the cells in a quad tree approach. This seems elaborate but not too bad. The link doesn't describe anything so sophisticated; it's just about smoothing a raster.

6 hours ago, Shaarigan said:

Terrain generation is an interesting area so you might read further about it for example at this site providing a lot of papers about terrain generation and optimization algorithms

That website is a wonderful resource. Unfortunately it doesn't seem to have any road embedding algorithms, but I am glad to have found it. Thank you.

The only "algorithm" I could find so quick was in this StackOverflow question but the problem needs a little bit of adjustment. When you found the vertices matching the road spline vertices you need to just couple them, move the terrain vertices to fit into your road vertices or add your road vertices into your terrain VBO or however you are going to solve this.

 

15 hours ago, Outliner said:

it's just about smoothing a raster

And this is how you need to do it. You get blocky looking areas when height values are in avarage above certain threshold. You then need to find those areas and add additional vertices between two of those over-threshold valued height values to make the resolution higher and let the mesh look smooth.

 

At the end you either need to reinvent the wheel on certain circumstances because the big players payed people for this and dont give the infos away right now or someone in similar situation decided to go other ways to solve this, who knows :)

On 10/26/2017 at 12:17 AM, Shaarigan said:

At the end you either need to reinvent the wheel on certain circumstances because the big players payed people for this and dont give the infos away.

In this case we're trying to invent something quite tricky. Moving the vertices of one mesh to match another is not a simple thing, and the more I think about it the more I wonder where I'd even start on an algorithm to do that. If there's no way to research this on the internet, then perhaps it's not a practical option.

On 10/26/2017 at 12:17 AM, Shaarigan said:

The only "algorithm" I could find so quick was in this StackOverflow question but the problem needs a little bit of adjustment.

I've seen the StackOverflow question before, but at the time I was focused on other approaches to the problem. Now that I look at it more seriously, it at least seems easier than what you're suggesting. We just need  some particular spline algorithms. We need a spline with thickness to represent the river/road. We need an algorithm to iterate through the grid vertices covered by the thick spline. We need an algorithm to determine the intersection point between a line segment and the boundary of the thick spline. We remove every grid vertex covered by the thick spline and add new vertices for the intersection points, then connect these new vertices in order along the boundary of the spline to form the edge of the river/road. I suspect we'll want to store the mesh as a half-edge structure to allow us to more easily insert arbitrary edges into the mesh, with a 2D array to allow us to look up grid vertices by their grid coordinates.

Even though I can imagine how it might be done, it seems complicated enough that I wonder if there might be a better way to solve this whole problem. Nothing in the design document demands that the roads be represented as splines or that the terrain must have a height map.

This topic is closed to new replies.

Advertisement