Add biome generation in engine
Currently, performance seems an issue - the cause of the effects is to be determined.pull/1/head
parent
b9e18f70eb
commit
acfdea349f
6
API.md
6
API.md
|
@ -126,6 +126,12 @@ The biomes are defined as follows:
|
|||
node_roof = "foo:bluestone",
|
||||
-- Node forming the ceiling of the cave
|
||||
|
||||
node_air = "foo:air",
|
||||
-- Nodes filling the inside of the cave. By default, this is air.
|
||||
-- You can replace it with e.g. water to make the entire cave a water cave.
|
||||
-- Keep in mind that cave biomes can blend, so it might not always look
|
||||
-- very smooth.
|
||||
|
||||
node_shell = "foo:permafrost",
|
||||
depth_shell = 3,
|
||||
-- Node forming a layer around the entire cave and thickness of this layer
|
||||
|
|
3
init.lua
3
init.lua
|
@ -11,6 +11,9 @@ noordstar_caves = {}
|
|||
-- Load features to influence cave shapes
|
||||
load("shape")
|
||||
|
||||
-- Load features to influence cave biomes
|
||||
load("biome")
|
||||
|
||||
-- Start engine to generate caves
|
||||
load("engine")
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ local function clean_def(def)
|
|||
if type(def.node_roof) == "string" then
|
||||
d.node_roof = def.node_roof
|
||||
end
|
||||
if type(def.node_air) == "string" then
|
||||
d.node_air = def.node_air
|
||||
end
|
||||
if type(def.node_shell) == "string" then
|
||||
d.node_shell = def.node_shell
|
||||
end
|
||||
|
|
112
lua/engine.lua
112
lua/engine.lua
|
@ -2,6 +2,38 @@
|
|||
-- Constants and magic numbers
|
||||
local mapgen_buffer = 16
|
||||
|
||||
-- Noise params for heat_point
|
||||
local heat_noise_params =
|
||||
{ offset = 50
|
||||
, scale = 50
|
||||
, spread = { x = 200, y = 200, z = 200 }
|
||||
, seed = 320523
|
||||
, octaves = 2
|
||||
, persistence = 0.1
|
||||
, lacunarity = 2.0
|
||||
, flags = ""
|
||||
}
|
||||
|
||||
-- Noise params for humidity_point
|
||||
local humidity_noise_params =
|
||||
{ offset = 50
|
||||
, scale = 50
|
||||
, spread = { x = 200, y = 200, z = 200 }
|
||||
, seed = 9923473
|
||||
, octaves = 2
|
||||
, persistence = 0.1
|
||||
, lacunarity = 2.0
|
||||
, flags = ""
|
||||
}
|
||||
|
||||
local default_biome =
|
||||
{ name = "noordstar_caves:none"
|
||||
, heat_point = -1e6
|
||||
, humidity_point = -1e6
|
||||
, minp = { x = -1e5, y = -1e5, z = -1e5 }
|
||||
, maxp = { x = 1e5, y = 1e5, z = 1e5 }
|
||||
}
|
||||
|
||||
-- Convert 3d relative coordinates to an index on a flat array
|
||||
local function from_3d_to_flat(dx, dy, dz, nx, ny)
|
||||
return (nx * ny * dz) + (nx * dy) + dx + 1
|
||||
|
@ -421,6 +453,46 @@ local function get_flat_cave_node_types(minp, maxp)
|
|||
end)
|
||||
end
|
||||
|
||||
-- Transform categorized blocks into
|
||||
local function biome_def_to_content_id(def, nt, original_block)
|
||||
local function get_node(name, alt)
|
||||
return function()
|
||||
if name == nil then
|
||||
return alt
|
||||
else
|
||||
return minetest.get_content_id(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local node_air = get_node(def.node_air, minetest.get_content_id("air"))
|
||||
local node_floor = get_node(def.node_floor, original_block)
|
||||
local node_stone = original_block
|
||||
local node_roof = get_node(def.node_roof, original_block)
|
||||
local node_unknown = original_block
|
||||
local node_wall = get_node(def.node_wall, original_block)
|
||||
|
||||
if nt == node_type.unknown then
|
||||
return node_unknown
|
||||
elseif nt == node_type.floor then
|
||||
return node_floor()
|
||||
elseif nt == node_type.wall then
|
||||
return node_wall()
|
||||
elseif nt == node_type.roof then
|
||||
return node_roof()
|
||||
elseif nt == node_type.content then
|
||||
return node_air()
|
||||
elseif nt == node_type.stone then
|
||||
return node_stone
|
||||
else
|
||||
return original_block
|
||||
end
|
||||
end
|
||||
|
||||
local function biome_distance(def, heat, humidity)
|
||||
return (def.heat_point - heat)^2 + (def.humidity_point - humidity)^2
|
||||
end
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
local vminp =
|
||||
{ x = minp.x - mapgen_buffer
|
||||
|
@ -440,29 +512,35 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
|
|||
-- Get threshold values
|
||||
local node_types = get_flat_cave_node_types(vminp, vmaxp)
|
||||
|
||||
local node_air = minetest.get_content_id("air")
|
||||
local node_floor = minetest.get_content_id("mcl_core:glass_green")
|
||||
local node_wall = minetest.get_content_id("mcl_core:glass_purple")
|
||||
local node_roof = minetest.get_content_id("mcl_core:glass_red")
|
||||
local node_other = minetest.get_content_id("mcl_core:glass")
|
||||
local heat_points = get_flat_from_noise_params(minp, maxp, heat_noise_params)
|
||||
local humidity_points = get_flat_from_noise_params(minp, maxp, humidity_noise_params)
|
||||
|
||||
-- Map block values
|
||||
local nids = Flat3dArray:from_func(vminp, vmaxp, function(i, pos)
|
||||
local nt = node_types:get_pos(pos)
|
||||
|
||||
if not is_valid_pos(pos, minp, maxp) then
|
||||
return flat_data:get_pos(pos)
|
||||
elseif nt == node_type.unknown then
|
||||
return node_other
|
||||
elseif nt == node_type.floor then
|
||||
return node_floor
|
||||
elseif nt == node_type.wall then
|
||||
return node_wall
|
||||
elseif nt == node_type.roof then
|
||||
return node_roof
|
||||
elseif nt == node_type.content then
|
||||
return node_air
|
||||
elseif nt == node_type.stone then
|
||||
return flat_data:get_pos(pos)
|
||||
else
|
||||
local biome = default_biome
|
||||
|
||||
local heat = heat_points:get_pos(pos)
|
||||
local humidity = humidity_points:get_pos(pos)
|
||||
|
||||
for _, def in pairs(noordstar_caves.registered_biomes) do
|
||||
if pos.x < def.minp.x then
|
||||
elseif pos.y < def.minp.y then
|
||||
elseif pos.z < def.minp.z then
|
||||
elseif pos.x > def.maxp.x then
|
||||
elseif pos.y > def.maxp.y then
|
||||
elseif pos.z > def.maxp.z then
|
||||
elseif biome_distance(def, heat, humidity) > biome_distance(biome, heat, humidity) then
|
||||
else
|
||||
biome = def
|
||||
end
|
||||
end
|
||||
|
||||
return biome_def_to_content_id(biome, nt, flat_data:get_pos(pos))
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
Loading…
Reference in New Issue