Page 1 of 1

Ideas for some new Ore Generation Types

PostPosted: Wed Aug 14, 2013 21:36
by SegFault22
I am here to make a suggestion, for some new ''types'' of ore generation (like Scatter, Sheet, etc.), that I think would have logical application.
  • ''Rare''
    ''Rare''-type would be a type very similar to Scatter, except that it takes on a different parameter for rarity. The parameter basically defines ''one out of <number> chunks will generate a cluster''. Cluster size, nodes per cluster, etc. are identical to Scatter-type. This will allow modders to add very rare, ''endgame-tier'' materials/items, for use in the highest-tier stuffs in their mods. This is not possible with Scatter generation, as it crashes after about 1/24/24/24 rarity.
  • ''Mega-cluster''
    ''Mega-cluster'' (it will be called something else) would be a type, similar to Rare, except that it can generate much more than one cluster per chunk, and takes on a parameter that basically defines ''<number> of directly adjacent (faces are connected) chunks will generate clusters''. This would allow modders to implement ores that generate in large areas of clusters that are far apart, to make the generation seem ''more realistic'', and allow miners of such ores to create mines in areas that have a lot of that ore. This would be more realistic than scatter-type generation because miners would ''prospect for deposits'' with tunnels, and establish a mine where they find an ore, rather than mining in any direction, hoping to happen upon something they need.
Please let me know if these ideas could be clarified, enhanced, or should be changed in any way; it is best that they make sense and are logical, so that people do not mis-understand the ideas presented.

PostPosted: Wed Aug 14, 2013 22:54
by paramat
Good ideas.

PostPosted: Thu Aug 15, 2013 16:04
by Mossmanikin
Your ideas absolutely make sense to me.
It would be very nice to have a gold mine here and a coal mine there (for example).
I mean: the game is called "Minetest", right?

PostPosted: Thu Aug 15, 2013 16:15
by Casimir
Something to start with.
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
perlinore = {}

function perlinore.generate_ore(
                                minp, maxp, seed,
                                name, wherein,
                                height_min, height_max,
                                inverse_chance, scale, noise_min, noise_max
                                )
--    local t1 = os.clock()
    if maxp.y < height_min or minp.y > height_max then
        return
    end
    local pr = PseudoRandom(seed)
    local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
    local a = VoxelArea:new{
            MinEdge={x=emin.x, y=emin.y, z=emin.z},
            MaxEdge={x=emax.x, y=emax.y, z=emax.z},
    }

    local data = vm:get_data()

    local c_ore  = minetest.get_content_id(name)

    local sidelen = maxp.x - minp.x + 1

    local noise = minetest.get_perlin_map(
            {offset=0, scale=1, spread={x=scale, y=scale, z=scale}, seed=5, octaves=5, persist=0.6},
            {x=sidelen, y=sidelen, z=sidelen}
    )
    local nvals = noise:get3dMap_flat({x=minp.x, y=minp.y, z=minp.z})

    local ni = 1
    for z = minp.z, maxp.z do
    for y = minp.y, maxp.y do
    for x = minp.x, maxp.x do
            if nvals[ni] > noise_min and nvals[ni] < noise_max then
                local pos={x=x,y=y,z=z}
                if minetest.get_node(pos).name == wherein then
                    if pr:next(1,inverse_chance) == 1 then
                        local vi = a:index(x, y, z)
                        data[vi] = c_ore
                    end
                end
            end
            ni = ni + 1
    end
    end
    end

    vm:set_data(data)
     
    vm:calc_lighting(
            {x=minp.x-16, y=minp.y, z=minp.z-16},
            {x=maxp.x+16, y=maxp.y, z=maxp.z+16}
    )

    vm:write_to_map(data)
 
--    print(string.format("elapsed time: %.2fms", (os.clock() - t1) * 1000))
end

minetest.register_on_generated(function(minp, maxp, seed)
    perlinore.generate_ore(
        minp, maxp, seed,
        "default:stone_with_coal",     "default:stone",    -- name, wherein
        -20000,  64,                                    -- height_min, height_max
        6, 300, -0.02, 0.02                                -- inverse chance, scale, noise_min, noise_max
    )
end)

Example for something very rare.
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)
    perlinore.generate_ore(
        minp, maxp, seed,
        "default:mese_block",     "default:stone",    -- name, wherein
        -30000,  64,                                    -- height_min, height_max
        4, 700, 1.99, 2.00                                -- inverse chance, scale, noise_min, noise_max
    )
end)

PostPosted: Thu Aug 15, 2013 18:30
by SegFault22
Casimir wrote:Something to start with.
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
perlinore = {}

function perlinore.generate_ore(
                                minp, maxp, seed,
                                name, wherein,
                                height_min, height_max,
                                inverse_chance, scale, noise_min, noise_max
                                )
--    local t1 = os.clock()
    if maxp.y < height_min or minp.y > height_max then
        return
    end
    local pr = PseudoRandom(seed)
    local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
    local a = VoxelArea:new{
            MinEdge={x=emin.x, y=emin.y, z=emin.z},
            MaxEdge={x=emax.x, y=emax.y, z=emax.z},
    }

    local data = vm:get_data()

    local c_ore  = minetest.get_content_id(name)

    local sidelen = maxp.x - minp.x + 1

    local noise = minetest.get_perlin_map(
            {offset=0, scale=1, spread={x=scale, y=scale, z=scale}, seed=5, octaves=5, persist=0.6},
            {x=sidelen, y=sidelen, z=sidelen}
    )
    local nvals = noise:get3dMap_flat({x=minp.x, y=minp.y, z=minp.z})

    local ni = 1
    for z = minp.z, maxp.z do
    for y = minp.y, maxp.y do
    for x = minp.x, maxp.x do
            if nvals[ni] > noise_min and nvals[ni] < noise_max then
                local pos={x=x,y=y,z=z}
                if minetest.get_node(pos).name == wherein then
                    if pr:next(1,inverse_chance) == 1 then
                        local vi = a:index(x, y, z)
                        data[vi] = c_ore
                    end
                end
            end
            ni = ni + 1
    end
    end
    end

    vm:set_data(data)
     
    vm:calc_lighting(
            {x=minp.x-16, y=minp.y, z=minp.z-16},
            {x=maxp.x+16, y=maxp.y, z=maxp.z+16}
    )

    vm:write_to_map(data)
 
--    print(string.format("elapsed time: %.2fms", (os.clock() - t1) * 1000))
end

minetest.register_on_generated(function(minp, maxp, seed)
    perlinore.generate_ore(
        minp, maxp, seed,
        "default:stone_with_coal",     "default:stone",    -- name, wherein
        -20000,  64,                                    -- height_min, height_max
        6, 300, -0.02, 0.02                                -- inverse chance, scale, noise_min, noise_max
    )
end)

Example for something very rare.
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)
    perlinore.generate_ore(
        minp, maxp, seed,
        "default:mese_block",     "default:stone",    -- name, wherein
        -30000,  64,                                    -- height_min, height_max
        4, 700, 1.99, 2.00                                -- inverse chance, scale, noise_min, noise_max
    )
end)

This looks promising. Before any of the suggested ore generation types are/may be implemented, may I use some of this code in my mod(s)?