1
\$\begingroup\$

I'm working on some procedural content for Unity3D - in C#

My main aim is to build a flat plane (or maybe later a terrain / mesh), with a single river running through it, based on a seed value.

I will keep the river throughout, but I will have 2 versions of a settlement, one medieval, later one urban city-like.

The over-arching function is basically:

  • Input an integer X (scale of settlement) and a seed integer Y
  • build a river, maybe roads next if I get the time
  • drop x buildings onto the map in a reasonable layout
  • once x reaches a pre-defined limit, switch to urban generation

I will probably populate both with generic assets from the asset store or similar, and hopefully will layout the buildings with a decent algorithm.

I've so far been able to generate a reasonably nice Voronoi Diagram using CSDelaunay by PouletFrit

The plan is to maybe treat Voronoi cells as farms for the Medieval time, and then switch form Euclidean Distance formula to Manhattan Distance Formula later for city road generation (but always keeping the same river)

I've converted the 2D code to generate a visual 3D Voronoi Diagram to help me learn the process and how the classes all work.

Examples

2D Voronoi, applied to a Texture2D, dots are 'sites'

2D Voronoi Diagram, applied to a Texture2D

3D with graph edge midpoints

3D Voronoi Diagram, using LineRenderers, Spheres etc.

I'm struggling with my next step from a planning point of view. In order to build a river through the diagram that looks reasonably well, I might use the method explained in Amit Patel's great procedural tutorial whereby splines are used, from edge midpoint to midpoint. and pick one arbitrary vertex on the north side, one on the south, and perform Dijkstra's algorithm to find the "best" (shortest) path for the river.

enter image description here

I have found a couple of very good spline tutorials such as the one from CatLikeCoding's AMAZING Curves and Splines tut.

but while writing this question I realised I have another option, I can just trace the edge midpoints and the cell 'sites' as in the image below, and increase the polygon (voronoi cell) count to make the river lines seem less angular. it's basic, but should work.

basic river line (hand-drawn)

So my main problem now is analysing what to do next.

In theory I could stay working in 2D, build a texture that has rivers and maybe roads, maybe pick more pixel colours for trees, rocks etc, and then instantiate the necessaries into the 3D world. But I'm not sure this is the best approach.

I could instead generate a 3D river using some of the great code explained in "Unite 2015 - A coder's guide to spline-based procedural geometry" and embed it onto a plane or similar, but it's at this point I am getting stuck in analysis paralysis. I can't really decide/determine at a high-level the best way to move forward.

The main questions I am struggling with:

  1. Should I generate a map of some sort in 2D and "extrude" details, or work in 3D from day one ? (main issue here is once I have a list of Vector3 for a river, how do I "apply" it to a plane or terrain ?

  2. Should I use a "shortest path" algorithm for the river (traverse the graph in some way), or generate an independent sine wave with nice looking meanders based on sinuosity as per "Pi me a river"

  3. Should I figure out a way to turn each Voronoi cell into a mesh and/or class so I can explore the relationships between two cells, or is it enough to finally figure out out how the graph data structure is working, and move from there.

  4. I'm not sure how to layout the buildings later.

Why a flat terrain ?

I suppose it might be easier to maintain across the medieval and urban landscapes.

A nice-to-have would be some perlin-noise based terrain, which seems reasonably easy to generate a heightmap and build a terrain from there, but I'm pretty sure I will struggle to get any river algorithm I create to conform to the terrain properly, so I might stick to 2D for the moment.

I need to do this as much in code as possible, and hopefully I can write much of my own code rather than relying on libraries. However I'm not asking for any code help, just some advice to get me out of a rut, if anybody can help I would really appreciate it!

I realise that this sort of question may not be fitting the correct pattern for questions on the site, in which case I apologise, and you can close it off early.

Many thanks in advance.

\$\endgroup\$

closed as too broad by DMGregory Feb 27 '18 at 14:29

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ All of the strategies you describe sound feasible, and you could fruitfully pursue any of them that interests you. You haven't provided us any criteria by which to evaluate them though, so in the current phrasing we can't determine a "correct" answer. Any of these strategies could be what's right for your project, depending on your goals and preferences. Can you try to narrow down your post to a single specific question you want to answer, or a specific problem you want to solve? Or, if you're just looking to chat & gather opinions, Game Development Chat may be a better venue. \$\endgroup\$ – DMGregory Feb 27 '18 at 14:19
  • \$\begingroup\$ Understood DMGregory , and thank you. I agree on the lack of specifics, I really need to narrow this down more in my own mind first. \$\endgroup\$ – TheDavil Feb 27 '18 at 14:27
  • 1
    \$\begingroup\$ Okay, I'll put this on hold as too broad for now. If you find a way to focus it more tightly in an edit, users can vote to re-open it. \$\endgroup\$ – DMGregory Feb 27 '18 at 14:30
1
\$\begingroup\$

Why don't you just use the existing straightedges between each unique pair of voronoi cells - which are already natural boundaries - as river cells? You can just expand them widthwise, twist / splinify them and... voilà? You now have natural boundaries without having to split cells?

If you're ultimately going to be working in a 3D environment, then work in 3D from day 1. Unity and other 3D engines have 2D vectors supported in a 3D environment if you prefer to use those.

Your third question about meshes consists entirely in how you are going to use them. For now I would keep a separate mesh, but have superstructures that point the the start and end vertices of each island - we call these submeshes - within that greater mesh.

As for your third question, neither are we. How can we be, when we have no idea what you'll be doing with them? These are the kinds of things you have to make your own road with - we all do. What I can say is you would probably be better off laying out buildings in a separate mesh so you can turn that view on and off while rendering, allowing you to see terrain more clearly.

Lastly, why flat terrain? Because it is always wiser to start with planar - which is computationally efficient and easier to reason about - and go to varying heights later, as in a heightmap. The one exception can be where you wish ultimately to have overhangs in terrain, e.g. in MineCraft - but even there, heightmaps are used as an intermediate structure e.g. in LoD and lighting.

Conclusion With this many ifs and maybes in your question, there is no way to do much better answers than that given here.

\$\endgroup\$
  • \$\begingroup\$ Thank you A E, this is very good advice. I think more than anything I needed a nudge in the right direction. Sorry about the lack of specificity. about a week with no sleep now, our baby is teething. :-) I might re-edit the question or if I have a more coherent and single question, post that separately later. \$\endgroup\$ – TheDavil Feb 27 '18 at 14:26
  • \$\begingroup\$ @TheDavil You're welcome. Feel free to hit checkmark if it ends up being the one that helped you. Good luck with the teether. \$\endgroup\$ – Engineer Feb 27 '18 at 14:27
  • 1
    \$\begingroup\$ as it's closed for now, I've accepted this answer thank you both for your time ! \$\endgroup\$ – TheDavil Feb 27 '18 at 14:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.