Page 1 of 1

lua help: nil, table expected [solved]

PostPosted: Sun Feb 16, 2014 06:59
by i1abnrk
I have a lua error and I kEep trying to iron this out but my point (voxel) is nil when I try to pass it to the function in a mapgen. Here's the code. I need a fresh pair of eyes to spot the problem.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_on_generated(function(minp, maxp, seed)
    local limit={
        XMIN = -33000,
        XMAX = 33000,
        YMIN = 3000,
        YMAX = 5000,
        ZMIN = -33000,
        ZMAX = 33000,
    }
   
    local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
    local grid = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
    local data = vm:get_data()
   
    function get_matter(point)
        return minetest.get_node(point).name
    end
   
    function get_depth(point)
        local y0 = limit.YMIN
        local y1 = limit.YMAX
        local y = y0
        local pi = point
        while y <= y1 do
            if get_matter(pi) == "air" then
                return y
            end
            y = y + 1
            pi = above(pi)
        end
        return y1
    end
   
    function set_matter(point, material)
        data[grid:indexp(point)]=minetest.get_content_id(material)
    end
   
    function incrementY(point)
        local currentValue = math.floor(get_depth(point)) + 1
        if (currentValue >= limit.YMAX) then
            return
        else
            set_matter(point, "default:stone")
        end
    end
   
    function below(point)
        return {x=point.x,y=point.y-1,z=point.z}
    end

    function above(point)
        return {x=point.x,y=point.y+1,z=point.z}
    end

    function north(point)
        return {x=point.x,y=point.y,z=point.z-1}
    end

    function south(point)
        return {x=point.x,y=point.y,z=point.z+1}
    end

    function east(point)
        return {x=point.x-1, y=point.y, z=point.z}
    end

    function west(point)
        return {x=point.x+1, y=point.y, z=point.z}
    end

    function adjacent(point)
        return {point, above(point), below(point), north(point), south(point), east(point), west(point)}
    end
   
    function level_neigh(point)
        local neighbors = {point, north(point), south(point), east(point), west(point)}
        return neighbors
    end
   
    function sumOfNeighbors(point)
        local sum = 0
        for ni = 0, #level_neigh(point) do
            local nb=level_neigh(point)[ni]
            sum = sum + get_depth(nb)
        end
        return sum
    end
   
    function countNeighborsOnLevel(point)
        local sum = 0
        for ni = 0, #level_neigh(point) do
            local nb=level_neigh(point)[ni]
            if get_depth(point)==get_depth(nb) then
                sum = sum + 1
            end
        end
        return sum
    end
   
    function addOneHere(point)
        local seed = math.random()
        local chance_constant=0.04
        local plant = 0
        local sn = sumOfNeighbors(point)
        local cl = countNeighborsOnLevel(point)
        local chanceModifier = (1.0+(chance_constant * sn)) ^ cl
        plant = seed * chanceModifier
        return plant
    end
   
    function generate_chunk()
        local x0 = emin.x
        local x1 = emax.x
        local y0 = emin.y
        local z0 = emin.z
        local z1 = emax.z
        for dz = z0, z1 do
            for dx = x0, x1 do
                local vi = grid:index(dx, y0, dz)
                local point = grid:position(vi)
                if addOneHere(point) >= 1.0 then
                    incrementY(point)
                end
            end
        end
    end
   
    generate_chunk()
   
    vm:set_data(data)
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
vm:update_liquids()
vm:write_to_map(data)
vm:update_map()
end)

Thanks, guys. Again, I'm nil hunting here. Might I suggest a separate thread for Lua questions?

PostPosted: Sun Feb 16, 2014 10:19
by i1abnrk
The stack trace starts at get_matter(point) with "attempting to index a nil" meaning x, y or z properties are not being set from VoxelArea:position or is being changed to a nil by my code.

PostPosted: Sun Feb 16, 2014 11:34
by rubenwardy
Try

minetest:get_node

PostPosted: Sun Feb 16, 2014 13:39
by i1abnrk
No, that doesn't work. I use the correct form of the get_node method according to the developer wiki. It seems to be nil from the generate_chunk function but it looks correct to me. Somewhere, I'm referencing and passing another value like perhaps the index instead of the table.

PostPosted: Sun Feb 16, 2014 14:36
by Krock
1) take your "limit" table outside of the function
2) take the other function in that function outside
3) test it
4) exact error messages increase your chance for getting help

PostPosted: Sun Feb 16, 2014 15:40
by i1abnrk
Ok, tables are 1-based and I had written 0-based loops in my sum functions. Yay for the print function. Functions in functions work fine for me and make my code cleaner. Moving things around though gave me the idea to generate debug output. (Duh-copter.) Thanks for the impetus, Krock.