# 2D Rivers/Lakes in infinite terrain

## 2D Rivers/Lakes in infinite terrain

```I've been looking into generating lakes and rivers for a 2D infinite tilemap but I'm stuck with how to handle them for an infinite map.
I can use noise/heightmaps for determining the lakes and the starting points for rivers but for an infinite map I can't use the  "flow downhill" or "carve out" technique because the player could come across the river at any point.
If I have a river that's a max of 200 tiles long, I'd have to calculate noise/map values for 33x33 chunks (my chunks are 6x6 tiles) around the player which feels excessive and very inefficient.
I have not found a way to make noise alone work for this, rivers would always be too circular if I find a range narrow enough and they'd encircle lakes, not extend outward.
Calculating voronoi cells and putting rivers at certain edges, with some extra noise to make the paths more natural, might work.
I just can't seem to find any good examples where they aren't working with known-dimension maps.
```

Take a look at this resource: http://martindevans.me/game-development/2015/12/11/Procedural-Generation-For-Dummies-Roads/

In short, I think you could treat a river in a similar manner as a road in that example. Let’s say you are using simple perlin-noise as a heightfield. You can then sample that heightfield at any point to generate an uphill/downhill vector for that location in space using a formula like the one listed below, and you can then use that vector to trace out the route of a river. E.G. start at a random seed position, sample the vector field, step in the direction of the vector, iterate like this until the route has traveled a certain number of steps, or doubles back on itself, or goes uphill, or collides with another route, etc. As will all things procedural, it will take a lot of fiddling to achieve a believable result.

heightfield-to-vectorfield pseudocode:

``````float v = SampleHeightField(position);
float x = SampleHeightField(new Vector2(position.x + .5f, position.y));
float y = SampleHeightField(new Vector2(position.x, position.y + .5f));

Vector2 fieldVector = new Vector2(v-x,v-y);
``````