diff --git a/README.txt b/README.txt index 2bea3d7..70ecbc7 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,4 @@ -noise23 0.1.1 by paramat -For latest stable Minetest back to 0.4.8 +noise23 0.2.0 by paramat +For Minetest 0.4.11 and later Depends default -Licenses: code WTFPL - -Enable fly, teleport to y = 7000 then fly up or down to find the surface. \ No newline at end of file +License: code WTFPL diff --git a/init.lua b/init.lua index 6e70446..698ad5e 100644 --- a/init.lua +++ b/init.lua @@ -1,79 +1,57 @@ --- noise23 0.1.1 by paramat --- For latest stable Minetest and back to 0.4.8 --- Depends default --- License: code WTFPL - -- Parameters -local YMIN = 6000 -local YMAX = 8000 -local TERCEN = 7000 -- Terrain centre. Average terrain level -local YWATER = 7000 -- Approximate water surface y, is rounded down to near base of chunk -local TERSCA = 128 -- Terrain scale in nodes, typical height of mountains -local TSTONE = 0.04 -- Density threshold for stone, depth of stone below surface -local STABLE = 2 -- Minimum number of stacked stone nodes in column required to support sand +local YZERO = 0 -- Average world surface level +local TERSCA = 96 -- Vertical terrain scale +local YWATER = 1 +local STABLE = 2 -- Number of stone nodes required to support biome above +local TSTONE = 0.03 -- Controls depth of stone below surface +local YSAND = 4 -- Y of beach top +local TTUN = -0.4 -- Biome noise threshold for tundra +local TDES = 0.4 -- Biome noise threshold for desert --- 3D noise for terrain +-- Noise parameters + +-- 3D noise local np_terrain = { offset = 0, scale = 1, - spread = {x=512, y=256, z=512}, -- squashed perlin noise, y spread is half + spread = {x=384, y=256, z=384}, seed = 5900033, - octaves = 6, - persist = 0.67 + octaves = 5, + persist = 0.63, + lacunarity = 2.0, + --flags = "" } --- 2D noise for biomes +-- 2D noise local np_biome = { offset = 0, scale = 1, - spread = {x=512, y=512, z=512}, -- spread is still stated with xyz values + spread = {x=768, y=768, z=768}, seed = -188900, - octaves = 4, - persist = 0.5 + octaves = 3, + persist = 0.4, + lacunarity = 2.0, + --flags = "" } --- Stuff +-- Set mapgen parameters -noise23 = {} +minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) +end) -ywater = (80 * math.floor((YWATER + 32) / 80)) - 32 + 15 -- sets water surface to 16 nodes above chunk base +-- Initialize noise objects to nil --- Nodes - -minetest.register_node("noise23:flosand", { - description = "Turquoise Float Sand", - tiles = {"noise23_flosand.png"}, - groups = {crumbly=3, falling_node=1}, - sounds = default.node_sound_sand_defaults(), -}) - -minetest.register_node("noise23:stone", { - description = "N23 Stone", - tiles = {"default_stone.png"}, - groups = {cracky=3}, - drop = "default:stone", - sounds = default.node_sound_stone_defaults(), -}) - -minetest.register_node("noise23:desertstone", { - description = "N23 Desert Stone", - tiles = {"default_desert_stone.png"}, - groups = {cracky=3}, - drop = "default:desert_stone", - sounds = default.node_sound_stone_defaults(), -}) +local nobj_terrain = nil +local nobj_biome = nil -- On generated function minetest.register_on_generated(function(minp, maxp, seed) - if minp.y < YMIN or maxp.y > YMAX then - return - end - - local t1 = os.clock() + local t0 = os.clock() local x1 = maxp.x local y1 = maxp.y local z1 = maxp.z @@ -81,92 +59,135 @@ minetest.register_on_generated(function(minp, maxp, seed) local y0 = minp.y local z0 = minp.z - print ("[noise23] chunk minp ("..x0.." "..y0.." "..z0..")") - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} local data = vm:get_data() - local c_air = minetest.get_content_id("air") - local c_n23stone = minetest.get_content_id("noise23:stone") - local c_n23destone = minetest.get_content_id("noise23:desertstone") - local c_sand = minetest.get_content_id("default:sand") - local c_desand = minetest.get_content_id("default:desert_sand") - local c_flosand = minetest.get_content_id("noise23:flosand") - local c_water = minetest.get_content_id("default:water_source") - + local c_stone = minetest.get_content_id("default:stone") + local c_sand = minetest.get_content_id("default:sand") + local c_water = minetest.get_content_id("default:water_source") + local c_lava = minetest.get_content_id("default:lava_source") + local c_grass = minetest.get_content_id("default:dirt_with_grass") + local c_dirt = minetest.get_content_id("default:dirt") + local c_desand = minetest.get_content_id("default:desert_sand") + local c_destone = minetest.get_content_id("default:desert_stone") + local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") + local sidelen = x1 - x0 + 1 - local chulens = {x=sidelen, y=sidelen, z=sidelen} - local minposxyz = {x=x0, y=y0, z=z0} - local minposxz = {x=x0, y=z0} + local ystridevm = sidelen + 32 + --local zstridevm = ystride ^ 2 + local chulens3d = {x=sidelen, y=sidelen+17, z=sidelen} + local chulens2d = {x=sidelen, y=sidelen, z=1} + local minpos3d = {x=x0, y=y0-16, z=z0} + local minpos2d = {x=x0, y=z0} - local nvals_terrain = minetest.get_perlin_map(np_terrain, chulens):get3dMap_flat(minposxyz) - local nvals_biome = minetest.get_perlin_map(np_biome, chulens):get2dMap_flat(minposxz) + nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulens3d) + nobj_biome = nobj_biome or minetest.get_perlin_map(np_biome, chulens2d) - local nixyz = 1 -- 3D noise index - local nixz = 1 -- 2D noise index + local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d) + local nvals_biome = nobj_biome:get2dMap_flat(minpos2d) + + local ni3d = 1 + local ni2d = 1 local stable = {} - for z = z0, z1 do -- for each xy plane progressing northwards + local under = {} + for z = z0, z1 do for x = x0, x1 do local si = x - x0 + 1 - local nodename = minetest.get_node({x=x,y=y0-1,z=z}).name - if nodename == "air" - or nodename == "default:water_source" then - stable[si] = 0 - else - stable[si] = STABLE - end + stable[si] = 0 end - for y = y0, y1 do -- for each x row progressing upwards + for y = y0 - 16, y1 + 1 do local vi = area:index(x0, y, z) - for x = x0, x1 do -- for each node do + for x = x0, x1 do local si = x - x0 + 1 - local grad = (TERCEN - y) / TERSCA - local density = nvals_terrain[nixyz] + grad - local n_biome = nvals_biome[nixz] -- biome noise for node - local biome = false -- set biome id to undefined - if n_biome > 0.46 + math.random() * 0.04 then -- set biome id - biome = 3 - elseif n_biome < -0.5 + math.random() * 0.04 then - biome = 1 - else - biome = 2 - end - if density >= TSTONE then - if biome == 3 then - data[vi] = c_n23destone - else -- biomes 1 and 2 - data[vi] = c_n23stone + local viu = vi - ystridevm + local n_biome = nvals_biome[ni2d] + + local n_terrain = nvals_terrain[ni3d] + local grad = (YZERO - y) / TERSCA + local density = n_terrain + grad + + if y < y0 then + if density >= TSTONE then + stable[si] = stable[si] + 1 + elseif density <= 0 then + stable[si] = 0 end - stable[si] = stable[si] + 1 - elseif density >= 0 and density < TSTONE and stable[si] >= 2 then - if biome == 3 then - data[vi] = c_desand - elseif biome == 1 then - data[vi] = c_flosand - else -- biome = 2 - data[vi] = c_sand + if y == y0 - 1 then + local nodid = data[vi] + if nodid == c_stone + or nodid == c_destone + or nodid == c_sand + or nodid == c_desand + or nodid == c_grass + or nodid == c_dirt then + stable[si] = STABLE + end + end + elseif y >= y0 and y <= y1 then + if density >= TSTONE then + if n_biome > TDES then + data[vi] = c_destone + else + data[vi] = c_stone + end + stable[si] = stable[si] + 1 + under[si] = 0 + elseif density > 0 and density < TSTONE + and stable[si] >= STABLE then + if y <= YSAND then + data[vi] = c_sand + under[si] = 1 -- beach + elseif n_biome < TTUN then + data[vi] = c_dirt + under[si] = 4 -- tundra + elseif n_biome > TDES then + data[vi] = c_desand + under[si] = 3 -- desert + else + data[vi] = c_dirt + under[si] = 2 -- grassland + end + elseif y <= YWATER then + data[vi] = c_water + stable[si] = 0 + under[si] = 0 + else -- air, possibly just above surface + if under[si] == 2 then + data[viu] = c_grass + elseif under[si] == 4 then + data[viu] = c_dirtsnow + end + stable[si] = 0 + under[si] = 0 + end + elseif y == y1 + 1 then + if density <= 0 and y > YWATER then -- air, possibly just above surface + if under[si] == 2 then + data[viu] = c_grass + elseif under[si] == 4 then + data[viu] = c_dirtsnow + end + stable[si] = 0 + under[si] = 0 end - elseif y <= ywater then - data[vi] = c_water - stable[si] = 0 - else - data[vi] = c_air - stable[si] = 0 end - nixyz = nixyz + 1 -- increment 3D noise index - nixz = nixz + 1 -- increment 2D noise index + + ni3d = ni3d + 1 + ni2d = ni2d + 1 vi = vi + 1 end - nixz = nixz - 80 -- rewind 2D noise index by 80 nodes for next x row above + ni2d = ni2d - sidelen end - nixz = nixz + 80 -- fast-forward 2D noise index by 80 nodes for next northward xy plane + ni2d = ni2d + sidelen end vm:set_data(data) - vm:set_lighting({day=0, night=0}) vm:calc_lighting() vm:write_to_map(data) - local chugent = math.ceil((os.clock() - t1) * 1000) - print ("[noise23] "..chugent.." ms") -end) \ No newline at end of file + vm:update_liquids() + + local chugent = math.ceil((os.clock() - t0) * 1000) + print ("[noise23] "..chugent.." ms minp ("..x0.." "..y0.." "..z0..")") +end) + diff --git a/textures/noise23_flosand.png b/textures/noise23_flosand.png deleted file mode 100644 index 8ab3111..0000000 Binary files a/textures/noise23_flosand.png and /dev/null differ