Generating 'interesting' 2D tunnels

So I am working on a 2D escape/sidescrolling game.
Essentially ship flying through tunnel. Nothing too exciting.

However I am having issues solving tunnel generation. I want to generate the tunnel(s) of various sizes of up and down.

failed - Simple approach (just pick a random distance from y=0, for ‘bottom of tunnel’ then offset minimum random distance for ceiling
— While this does work, it never generates very nice looking curves or anything ‘interesting’

failed - bezier curves/splines
–generate various curves and connect them together, and offset for distances. A bit better, can generate some nice varied terrain, however it only ever produces various curves and not enough of ‘interesting’ or ‘variance’

I was hoping to go with a noise(perlin/simplex/???) approach for 2 reasons. More variance and ideally 1 of the ‘interesting’(occasionally floating islands?) things I would like is for it to split off occasionally, so that you could have a choice of going between 2 tunnels or more?

However, I cannot have ‘dead ends’ so if it splits, it needs to reconnect at some point or it perpetually has any number of tunnels? (bound to a particular height of world of course

I vaguely saw some things talking about ‘perlin worms’ or ‘perlin tunnels’ or ‘rivers’(such as on a 2d top down terrain map) However I couldn’t find much samples or code to reference from?

Any suggestions or links would be greatly appreciated!

edit: While I am not ready to post a WiP, if you need an example of what I am talking about. here is a rough concept of whats happening right now.
http://84bit.com/runnergame-desktop_fat.jar

edit2: going to bed, but going to attempt something else tomorrow?
Generate some perlin noise for map, then use A* to generate a path between some endpoints. Then distort the path with some midpoint displacement.
Possibly generating more than 1 path? Perhaps ill generate 2 worlds, 2 paths, then flatten them together? Seems like a lot of work but that could give 2 seperate paths(sometimes will be the same) and if they are ‘slightly’ off, they would be able to generate ‘islands’ Or find some way of ‘eroding’ the map based upon the paths? is there an easy way to do this?

  1. Move the position in a random direction.
  2. Clear a circle around the position.
  3. Repeat as much as you like. Also create branches if you want.

use value = Abs(noise)
the output would be like this:

Black is value around 0.
these are the best caves you could create using noise.

If you want an easier way to generate simple tunnels, you could also use this method:
http://roguebasin.roguelikedevelopment.org/index.php?title=Basic_directional_dungeon_generation
Its super simple, and you could use a* to connect the paths together. Of course, an actual noise algorithm would probably produce more interesting results but this way is easier and creates some interesting tunnels/caves.

Thanks all, exactly what i was hoping for !

I will try and implement them today and see how it works out!

I like the abs(noise) version because it can be made to wrap around or support generating seamless levels in chunks. A similar technique is to use the boundaries of a Voronoi diagram. It can be done without rasterizing, all areas will be connected, and most forks will have approximately equal angles. More noise could be used to displace/noisify the tunnels in either method.

I have seen a cellular automata algorithm (like Conway’s game of life) that generates large open spaces that look cave-like, but I do not have a link. This looks good for top-down and side views, but you can’t really distinguish tunnels from open spaces and extra work may be necessary to make everything connected.