Q: How to make a 4d array for terrain

I have been working with perlin for about a month now and want to move from 2d arrays to 3d arrays (In order to make caves) and would like to know how to make a 4d array to make one.

Why do you want 4d arrays when you need 3d arrays?

Anyway, you can make arrays of any dimensionality like this:

local _1d = { 1 }
local _2d = { {1, 2}, {3, 4} }
local _3d = {
    { {1, 2}, {3, 4} },
    { {5, 6}, {7, 8} }
}

and so forth. You can index into e.g. a 3d array like so:

local v = _3d[x][y][z]

You might want some helper functions:

function set3D(arr, x, y, z, value)
    arr[x][y][z] = value
end

function get3D(arr, x, y, z)
    return arr[x][y][z]
end

I usually add logic to those functions to automatically set up sub-arrays inside set3D only when needed. That way I don’t have to ensure that the table is set up before hand. That effectively makes them into sparse, jagged arrays. If you want non-sparse, rectangular arrays you can set those up with another helper function:

function make3DArray(sx, sy, sz, default)
    local arr = {}
    for x = 1, sx do
        arr[x] = {}
        for y = 1, sy do
            arr[x][y] = {}
            if default == nil then continue end
            for z = 1, sz do
                arr[x][y][z] = default
            end
        end
    end 
    return arr
end