Using Perlin worms for caves?

So I’m making a Minecraft clone (of course), and right now my caves a generated using Perlin/simplex noise. This is great in all since I’ve got some caves, but these caves are way too big and spacy. Sure caves in real life can be like this, but to have a real caving experience you need to not be able to just fall down a cave to the bottom of the world, right? But here’s the thing. The caves in Minecraft are generated using Perlin worms, (I think) and therefore provide a really cool caving experience.

So the thing I need help with is (As you’ve probably guessed) generating caves with Perlin worms – even just a tutorial on something like “Perlin worms in Unity” would be massively appreciated.

I would be really happy if someone could help me with this… I’ve done endless google searches, and haven’t really found anything that’s helpful. So any help would be amazing.

Thanks to anyone in advance!

For anyone that’s having the same problem, here’s a random-walk/Perlin worms example:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class myPerlinWorm : MonoBehaviour
{
    public float speed;
    public float turnyness;
    public float heading;
    public GameObject prefab;
    float placementTimer = 0f;
    // Start is called before the first frame update
    void Start()
    {
        
    }
    private void Awake() {
        // defaults
		if (speed == 0)
		{
			speed = Random.Range( 2.0f, 5.0f);
			heading = Random.Range( 0.0f, 360.0f);
			turnyness = Random.Range( 1450.0f, 2600.0f);
		}
    }

    // Update is called once per frame
    void Update()
    {
        placementTimer += 0.1f;
        Vector3 position = transform.position;
        float x = position.x;
        float y = position.y;
        float noise = Mathf.PerlinNoise(x, y);
        noise -= 0.5f;
        float turn = noise * turnyness;
        Vector3 direction = Quaternion.Euler (0, 0, heading) * Vector3.up;
        heading += turn * Time.deltaTime;
        position += direction * (speed * Time.deltaTime);
        transform.position = position;

        if (placementTimer >= 3f)
        {
            Instantiate(prefab, new Vector3(Mathf.Round(position.x), Mathf.Round(position.y), Mathf.Round(position.z)), Quaternion.identity);
            placementTimer = 0f;
        }
    }
}