Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.59k stars 244 forks source link

Adding rivers and roads to smooth terrain #298

Open slapin opened 3 years ago

slapin commented 3 years ago

Seeing how advanced object placement became now I try to figure out the best approach to put roads on the terrain. I guess I can have an array of pre-generated line segments in memory (with some query optimization) and implement custom InstanceGenerator which would sample road segment which belongs to the current chunk if not already displayed (so need to track already spawned segments and remove ones when their chunk gets deleted). Does this sound sane or should I chose different approach (the actual line segments list is generated using one of roadmap algorithms)?

Zylann commented 3 years ago

Sounds sort of ok. If you know everything in advance then the problem boils down to storing it in a data structure that suits the chunked streaming system and serving results. The instancer then allows to spawn river meshes, but you might have been able to do this even before it got scene support by just layering the two systems, rather than intertwining them (the waterways and hterrain addons don't know each other, yet they combine nicely). Maybe the only thing the voxel terrain needs to know is where to carve riverbeds I guess, which is work for the ground generator.

In progressive proc-gen however, it sounds like a very complex problem to tackle. Generating isolated point of interests is easy because the individual areas you have to manage are limited, they have known borders. The instancer only just allows scenes now, it did not change much otherwise. Rivers and roads are interconnected things that can sprawl for large distances so it is hard to think of an efficient approach when the world has to generate progressively (hence why knowing it all in advance can help). If it goes in the same ballpark as structural generation, then it would have to use the same approach as cellular noise (have a grid, each cell generates stuff deterministically but never affects more than 1 neighbor away, so generating a cell is up to generating itself and its neighbors without actually needing to access neighbors).

On the other hand, maybe a simpler alternative, although with pros and cons: For rivers, Minecraft actually uses noise and produces relatively convincing results at player scale, but on world scale they dont make much sense, as there is no realistic structure (they can go in circles in land or start from sea and finish also in sea etc). Although it can be fine depending on the game. Roads could be obtained in a similar way using cellular noise and a mix of different distance functions to produce a more "organized" pattern going only in cardinal or diagonal directions. Although if game systems need the graph information then noise doesnt help. That's just theory I'm doing now, I have not researched on this subject yet.

Note: rivers suppose existence of voxel water management. Keep in mind one of the big points of this module is destructible environment. A river means water may flow as players dig around it. This is very hard to do efficiently. In the case of road meshes they could get cut in some way.

slapin commented 3 years ago

I have kind of upfront knowledge of road and river structure, so I just need to build road segments and intersections on chunks I guess. There are plans of some progressive updates but they will affect stored road data.

slapin commented 3 years ago

The road system is generated but as separate pass of world building.

Zireael07 commented 3 years ago

@slapin: I'd use something like https://github.com/Arnklit/Waterways ? It can snap to curve points and those can be set from script....