Post your mapgen questions here (modding or engine)

Winter94
Member
Posts: 44
Joined: Sat Jan 11, 2020 17:15
In-game: Azrael Winter WintersKnight

Re: Post your mapgen questions here (modding or engine)

by Winter94 » Post

My bad, I'll start keeping it confined to the 'Noob here, needing help...' thread that I made for this problem.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

It is better to do what i described earlier:

Clear the registered biomes, decorations and ores (in a mod that depends on 'default', 'butterflies', 'fireflies, and 'flowers' mods), then reregister biomes, decorations and ores with the desired changes.
If you do that then you will no longer need to use custom heat and humidity noises.

The clearing code is:

minetest.clear_registered_biomes()
minetest.clear_registered_decorations()
minetest.clear_registered_ores()

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

Copy-paste into the mod the biome, decoration and ore registrations from MTGame, and delete or edit them according to your needs.

qu4ntumrush
New member
Posts: 2
Joined: Sat Feb 15, 2020 07:44
GitHub: qu4ntumrush
In-game: qu4ntumrush

Re: Post your mapgen questions here (modding or engine)

by qu4ntumrush » Post

I want to use open-mapgen (posting here because the official thread is dead) for a school project and I have large DEMs (20 km wide) of Florida as GeoTIFFs I want to convert into Minetest maps. I get errors no matter which DEM I use or the mod's parameters including scaling down. Recently every error says this:

Code: Select all

zerr: invalid or incomplete deflate data
ModError: Failed to load and run script from C:\Games\minetest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:
decompressZlib: inflate failed
stack traceback:
	[C]: in function 'decompress'
	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:121: in main chunk
Check debug.txt for details.
I often try using a land cover and I may have had slightly more luck getting a map to load without it (I've lost track), but when it does load, it's completely flat so it must not be reading the DEM as a height map.

Other error messages I have gotten:

First error message I got when it was installed on my desktop before moving to C:\Games\Minetest\mods\:

Code: Select all

2020-02-11 02:24:06: ERROR[Main]: ModError: Failed to load and run script from C:\Users\[Me]\Desktop\minetest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:
2020-02-11 02:24:06: ERROR[Main]: ...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:34: attempt to index local 'str' (a nil value)
2020-02-11 02:24:06: ERROR[Main]: stack traceback:
2020-02-11 02:24:06: ERROR[Main]: 	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:34: in function 'parse'
2020-02-11 02:24:06: ERROR[Main]: 	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:105: in main chunk
2020-02-11 02:24:06: ERROR[Main]: Check debug.txt for details.
Once I ran the converter w/o land cover, the world opened but crashed:

Code: Select all

AsyncErr: Lua: finishGenRuntime error from mod 'geo_mapgen' in callback environment_OnGenerated(): decompressZlib: inflate failed
stack traceback:
	[C]: in function 'decompress'
	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:81: in function '__index'
	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:192: in function 'value'
	...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:231: in function <...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:195>
	...es\minetest-5.1.1-win64\bin\..\builtin\game\register.lua:429: in function <...es\minetest-5.1.1-win64\bin\..\builtin\game\register.lua:413>
I know nothing about Lua scripts and only basic Python knowledge (pip install, QGIS, etc.), so all I can understand from "invalid or incomplete deflate data" is that something is wrong with the compression or file format. Well it works perfectly fine in QGIS (I've used it to make hillshade and slope rasters, and I've even added height maps to Worldpainter but without land cover classes), but it also won't open in MicroDEM because "not acceptable DEM." If you must know, I downloaded from the NOAA Data Access Viewer and if the proper data is chosen, it should be multiple TIFF files with multiple world files and an index sheet shapefile. I don't know why open-mapgen and MicroDEM consider it corrupted whereas every other program can use it. This has driven me insane for three days now and ideally I would like to contact the original programmer (Gail de Sailly) directly, but I welcome any Lua experts for help.

User avatar
duane
Member
Posts: 1715
Joined: Wed Aug 19, 2015 19:11
GitHub: duane-r
Location: Oklahoma City
Contact:

Re: Post your mapgen questions here (modding or engine)

by duane » Post

qu4ntumrush wrote:I want to use open-mapgen (posting here because the official thread is dead) for a school project
I think you'd have better luck posting to the project thread, anyway. Gael de Sailly is more likely to monitor his own posts; but don't expect an immediate response, as he may not be working on minetest much these days. I don't have any experience with topographical maps, but I've worked closely with Gael de Sailly's code in the past. It usually looks straight-forward, but the principles can be insanely difficult.

You might want to make sure that the format for those maps hasn't changed in the last year or so. They might be using a different compression method.
Believe in people and you don't need to believe anything else.

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

Yes, best also post in the dedicated thread, then it will not be 'dead' =)
That mod is beyond my understanding.

User avatar
CBugDCoder
Member
Posts: 32
Joined: Tue Jul 31, 2018 12:13
GitHub: CBugDCoder
IRC: CBugDCoder
In-game: CalebDavis
Location: Home

Re: Post your mapgen questions here (modding or engine)

by CBugDCoder » Post

I am trying to generate wallmounted vines on the underside of floating islands. My inital plan was to use decorations and minetest.get_mapgen_object("gennotify") but the gennotify mapgen object does not include decorations placed in the VM. How would I get the locations of the vines without having to sort through all the nodes again?
My Mods: Mob AI Glider

User avatar
CBugDCoder
Member
Posts: 32
Joined: Tue Jul 31, 2018 12:13
GitHub: CBugDCoder
IRC: CBugDCoder
In-game: CalebDavis
Location: Home

Re: Post your mapgen questions here (modding or engine)

by CBugDCoder » Post

I was able to find them by only searching through the x and z axis and using the terrain noise values. But if anyone has a better solution I am open to them.
My Mods: Mob AI Glider

User avatar
CBugDCoder
Member
Posts: 32
Joined: Tue Jul 31, 2018 12:13
GitHub: CBugDCoder
IRC: CBugDCoder
In-game: CalebDavis
Location: Home

Re: Post your mapgen questions here (modding or engine)

by CBugDCoder » Post

Image
Image
Attachments
screenshot_20200218_094730.png
screenshot_20200218_094730.png (323.75 KiB) Viewed 2454 times
screenshot_20200218_094716.png
screenshot_20200218_094716.png (224.47 KiB) Viewed 2454 times
My Mods: Mob AI Glider

User avatar
firefox
Member
Posts: 1709
Joined: Wed Jan 14, 2015 07:34
In-game: Red_Fox
Location: Xanadu

Re: Post your mapgen questions here (modding or engine)

by firefox » Post

i read somewhere that it was possible to add x-z-limits to biomes.
but how would i do that?

according to the given y_min, y_max and vertical_blend, i tried x_min, x_max and horizontal_blend but nothing happened.
the mapgen still generates the biome all over the world, even though i set it to generate only on the +x side and another biome on the -x side.

i can't seem to find what i have read in the search either. but i clearly remember that it came with a screenshot and examples...
✨🏳️‍🌈♣️✨

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

https://github.com/minetest/minetest/bl ... .txt#L7181

Did you search through the documentation?
If using XYZ biome limits you must use the 'min_pos', 'max_pos' format.
Also, there is no 'horizontal blend'.

twoelk
Member
Posts: 1482
Joined: Fri Apr 19, 2013 16:19
GitHub: twoelk
IRC: twoelk
In-game: twoelk
Location: northern Germany

Re: Post your mapgen questions here (modding or engine)

by twoelk » Post

if only we could do this with mapgenerators as well :D

like in a different mapgen for every quadrant or maybe some 1000 meter wide mg5 blob in the center surrounded by mg7 terrain and in a strip of maybe 2000 m width along the map edges mg-valleys.

if only ...

minerman
Member
Posts: 23
Joined: Sat Mar 07, 2020 11:01

Re: Post your mapgen questions here (modding or engine)

by minerman » Post

How to increase the number of available dungeon in a map?
There is dungeon noise, but i dont understand the use of every params (every noise is different)

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

In dungeon noise, the 'offset' is the average number of dungeons per mapchunk, the 'scale' is the typical variation (of the number of dungeons per mapchunk) either side of 'offset'.

So for 2 dungeons per mapchunk everywhere: offset 2.0 scale 0.0
For a variation of 1-3 dungeons per mapchunk: offset 2.0 scale 1.0

minerman
Member
Posts: 23
Joined: Sat Mar 07, 2020 11:01

Re: Post your mapgen questions here (modding or engine)

by minerman » Post

paramat wrote:In dungeon noise, the 'offset' is the average number of dungeons per mapchunk, the 'scale' is the typical variation (of the number of dungeons per mapchunk) either side of 'offset'.

So for 2 dungeons per mapchunk everywhere: offset 2.0 scale 0.0
For a variation of 1-3 dungeons per mapchunk: offset 2.0 scale 1.0
Thank you!. Now i can make valley world filled with dungeons

User avatar
Walzy
New member
Posts: 2
Joined: Mon Mar 16, 2020 09:59
In-game: Walzy

Re: Post your mapgen questions here (modding or engine)

by Walzy » Post

How to add ores to the mapgen ?

User avatar
CBugDCoder
Member
Posts: 32
Joined: Tue Jul 31, 2018 12:13
GitHub: CBugDCoder
IRC: CBugDCoder
In-game: CalebDavis
Location: Home

Re: Post your mapgen questions here (modding or engine)

by CBugDCoder » Post

Use minetest.register_ore(ore_def) where ore_def is a table in the format described in https://rubenwardy.com/minetest_modding ... gister_ore
My Mods: Mob AI Glider

User avatar
Extex
Member
Posts: 244
Joined: Wed Mar 14, 2018 23:14
GitHub: Extex101
In-game: Extex

Re: Post your mapgen questions here (modding or engine)

by Extex » Post

I've got a singlenode with custom mapgen.
How do I place grass and dirt on the top areas?
Edit: It's a 3d mapgen if that is important
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP

ShadMOrdre
Member
Posts: 1118
Joined: Mon Dec 29, 2014 08:07
Location: USA

Re: Post your mapgen questions here (modding or engine)

by ShadMOrdre » Post

Extex,

Most mapgens I've seen determine the surface, and then drill down to place those.

You'll have to determine the surface. Once you do, you can use the biome definition data to determine how deep to go down for placing the filler and top nodes of the biome def.

The advantage is that as you find the surface and the biome, you can have your lua mapgen 2d index those to build a usable heightmap and biomemap for other mods.

I have not posted or otherwise shared the following code, but there is a whole lot of goodness in the code below. The gist of the mapgen code below is to use a voronoi diagram to influence terrain height. There are additional functions included as well.

The On_Gen call, at the bottom, is where you'll find my example of both heightmap and biomemap generation, once I've determined both the surface height and biome.

For a 3D mapgen, you have to determine what factor makes the surface, since the 3D noise value is more a true/false versus a hardcoded y-value. This can be tricky.

Code: Select all


minetest.set_mapgen_setting('mg_name','singlenode',true)
minetest.set_mapgen_setting('flags','nolight',true)
--minetest.set_mapgen_params({mgname="singlenode"})

--local storage = minetest.get_mod_storage()

local mg_map_view = false


local c_desertsandstone	= minetest.get_content_id("lib_materials:stone_sandstone_desert")
local c_sandstone	= minetest.get_content_id("lib_materials:stone_sandstone")
local c_desertstone	= minetest.get_content_id("lib_materials:stone_desert")
local c_stone		= minetest.get_content_id("lib_materials:stone")
local c_desertsand	= minetest.get_content_id("lib_materials:sand_desert")
local c_sand		= minetest.get_content_id("lib_materials:sand")
local c_brick		= minetest.get_content_id("lib_materials:stone_brick")
local c_block		= minetest.get_content_id("lib_materials:stone_block")
local c_desertstoneblock= minetest.get_content_id("lib_materials:stone_desert_block")
local c_desertstonebrick= minetest.get_content_id("lib_materials:stone_desert_brick")
local c_obsidian	= minetest.get_content_id("lib_materials:stone_obsidian")
local c_dirt		= minetest.get_content_id("lib_materials:dirt")
local c_dirtgrass	= minetest.get_content_id("lib_materials:dirt_with_grass")
local c_dirtdrygrass	= minetest.get_content_id("lib_materials:dirt_with_grass_dry")
local c_top		= minetest.get_content_id("lib_materials:dirt_with_litter_coniferous")
local c_snow		= minetest.get_content_id("lib_materials:dirt_with_snow")
local c_water		= minetest.get_content_id("lib_materials:liquid_water_source")
local c_tree		= minetest.get_content_id("lib_ecology:tree_default_trunk")
local c_air		= minetest.get_content_id("air")
local c_ignore		= minetest.get_content_id("ignore")

local fill_depth = 4
local top_depth = 1

local map_world_size
if mg_map_view == false then
	map_world_size = 62000
else
	map_world_size = 1000
end
local map_base_scale = 100
local map_size_scale = 10
--local map_scale = map_base_scale * map_size_scale
local map_scale = map_base_scale * map_size_scale
local map_noise_scale_multiplier = 3
local map_tectonic_scale = map_world_size / map_scale
local map_noise_scale = map_tectonic_scale * map_noise_scale_multiplier

				--31	--29	--43	--17	--330	--83
local voronoi_cells = 31
local heightmap_base = 5
local noisemap_base = 7
local cliffmap_base = 7
		
local abs   = math.abs
local max   = math.max
local sqrt  = math.sqrt
local floor = math.floor

local convex = false
local mult = lib_materials.mapgen_scale_factor or 4

local mg_golden_ratio = ((1 + (5^0.5)) * 0.5)

--[[
local np_terrain = {
	offset = -4,
	scale = map_noise_scale,
	seed = 5934,
	spread = {x = map_world_size/map_size_scale, y = map_world_size/map_size_scale, z = map_world_size/map_size_scale},
	octaves = 5,
	persist = 0.6,
	lacunarity = 2.11,
	--flags = "defaults"
}
--]]
local np_terrain = {
	offset = -4,
	scale = 50,
	seed = 5934,
	spread = {x = 2400, y = 2400, z = 2400},
	octaves = 8,
	persist = 0.4,
	lacunarity = 2.11,
	--flags = "defaults"
}
local np_cliffs = {
	offset = 0,					
	scale = 0.72,
	spread = {x = 180*mult, y =180*mult, z = 180*mult},
	seed = 78901,
	octaves = 2,
	persist = 0.4,
	lacunarity = 2.11,
--	flags = "absvalue"
}
local np_heat = {
	flags = "defaults",
	lacunarity = 2,
	offset = 50,
	scale = 50,
	spread = {x = 1000, y = 1000, z = 1000},
	seed = 5349,
	octaves = 3,
	persistence = 0.5,
}
local np_heat_blend = {
	flags = "defaults",
	lacunarity = 2,
	offset = 0,
	scale = 1.5,
	spread = {x = 8, y = 8, z = 8},
	seed = 13,
	octaves = 2,
	persistence = 1,
}
local np_humid = {
	flags = "defaults",
	lacunarity = 2,
	offset = 50,
	scale = 50,
	spread = {x = 1000, y = 1000, z = 1000},
	seed = 842,
	octaves = 3,
	persistence = 0.5,
}
local np_humid_blend = {
	flags = "defaults",
	lacunarity = 2,
	offset = 0,
	scale = 1.5,
	spread = {x = 8, y = 8, z = 8},
	seed = 90003,
	octaves = 2,
	persistence = 1,
}

local v_points = {
	{x=-350,z=-350},
	{x=-35,z=-350},
	{x=-135,z=-135},
	{x=-35,z=-35},
	{x=-350,z=350},
	{x=-350,z=35},
	{x=-135,z=135},
	{x=-35,z=35},
	{x=350,z=-350},
	{x=35,z=350},
	{x=135,z=-135},
	{x=35,z=-35},
	{x=350,z=350},
	{x=350,z=-35},
	{x=135,z=135},
}

local nobj_terrain = nil
--local nbase_terrain = nil
local isln_terrain = nil

local nobj_cliffs = nil
local isln_cliffs = nil

local nobj_heatmap = nil
local nbase_heatmap = nil
local nobj_heatblend = nil
local nbase_heatblend = nil
local nobj_humiditymap = nil
local nbase_humiditymap = nil
local nobj_humidityblend = nil
local nbase_humidityblend = nil

local mg_custom_data = {}

lib_mg_continental.heightmap = {}
lib_mg_continental.biomemap = {} 

local hills_offset = 64*mult
local hills_thresh = math.floor((np_terrain.scale)*0.5)
local shelf_thresh = math.floor((np_terrain.scale)*0.5) 
local cliffs_thresh = math.floor((np_terrain.scale)*0.5)

local function max_height(noiseprm)
	local height = 0					--	30		18
	local scale = noiseprm.scale				--	18		10.8
	for i=1,noiseprm.octaves do				--	10.8		6.48
		height=height + scale				--	6.48		3.88
		scale = scale * noiseprm.persist		--	3.88		2.328
	end							--	-----		------
	return height+noiseprm.offset				--			41.496 + (-4)
end								--			37.496

local function min_height(noiseprm)
	local height = 0
	local scale = noiseprm.scale
	for i=1,noiseprm.octaves do
		height=height - scale
		scale = scale * noiseprm.persist
	end	
	return height+noiseprm.offset
end

local base_min = min_height(np_terrain)
local base_max = max_height(np_terrain)
local base_rng = base_max-base_min
local easing_factor = 1/(base_max*base_max*4)

local function get_terrain_height_shelf(theight)
		-- parabolic gradient
	if theight > 0 and theight < shelf_thresh then
		theight = theight * (theight*theight/(shelf_thresh*shelf_thresh)*0.5 + 0.5)
	end

	return theight
end

local function get_terrain_height_hills_adjustable_shelf(theight,hheight,cheight,shlf_thresh)
		-- parabolic gradient
	if theight > 0 and theight < shlf_thresh then
		theight = theight * (theight*theight/(shlf_thresh*shlf_thresh)*0.5 + 0.5)
	end	
		-- hills
	if theight > hills_thresh then
		theight = theight + math.max((theight-hills_thresh) * hheight,0)
		-- cliffs
	elseif theight > 1 and theight < hills_thresh then 
		local clifh = math.max(math.min(cheight,1),0) 
		if clifh > 0 then
			clifh = -1*(clifh-1)*(clifh-1) + 1
			theight = theight + (hills_thresh-theight) * clifh * ((theight<2) and theight-1 or 1)
		end
	end
	return theight
end

local function get_distance(a,b)						--get_distance(a,b)
    return (max(abs(a.x-b.x), abs(a.y-b.y)))					--returns the chebyshev distance between two points
end

local function get_avg_distance(a,b)						--get_avg_distance(a,b)
    return ((abs(a.x-b.x) + abs(a.y-b.y)) * 0.5)					--returns the average distance between two points
end

local function get_manhattan_distance(a,b)					--get_manhattan_distance(a,b)
    return (abs(a.x-b.x) + abs(a.y-b.y))					--returns the manhattan distance between two points
end

local function get_euclid_distance(a,b)
	local dx = a.x - b.x
	local dy = a.y - b.y
	return (dx*dx+dy*dy)^0.5
end

local function get_midpoint(a,b)						--get_midpoint(a,b)
	return ((a.x+b.x)/2), ((a.y+b.y)/2)					--returns the midpoint between two points
end

--
-- save list of generated lib_mg_continental
--
function lib_mg_continental.save(pobj, pfilename)
  local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "w")
  if file then
    file:write(minetest.serialize(pobj))
    file:close()
  end
end
--
-- load list of generated lib_mg_continental
--
function lib_mg_continental.load(pfilename)
	local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "r")
	if file then
		local table = minetest.deserialize(file:read("*all"))
		if type(table) == "table" then
			return table
		end
	end
	--return {}
	return nil
end

--
-- save .csv file format
--
function lib_mg_continental.save_csv(pobj, pfilename)
	local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "w")
	if file then
		file:write(pobj)
		file:close()
	end
end

function lib_mg_continental.load_csv(separator, path)
	local file = io.open(lib_mg_continental.path_world.."/"..path, "r")
	if file then
		local t = {}
		for line in file:lines() do
			if line:sub(1,1) ~= "#" and line:find("[^%"..separator.."% ]") then
				table.insert(t, line:split(separator, true))
			end
		end
		if type(t) == "table" then
			return t
		end
	end
	--return {}
	return nil
end

-- Create a table of biome ids, so I can use the biomemap.
if not lib_mg_continental.biome_ids then

	--local get_cid = minetest.get_content_id
	lib_mg_continental.biome_info = {}

	for name, desc in pairs(minetest.registered_biomes) do

		local b_cid = minetest.get_biome_id(name)

		local b_top = minetest.get_content_id(desc.node_top)
		local b_top_depth = desc.depth_top or ""
		local b_filler = minetest.get_content_id(desc.node_filler)
		local b_filler_depth = desc.depth_filler or ""
		local b_stone = minetest.get_content_id(desc.node_stone)
		local b_water_top = minetest.get_content_id(desc.node_water_top)
		local b_water_top_depth = desc.depth_water_top or ""
		local b_water = minetest.get_content_id(desc.node_water)
		local b_river = minetest.get_content_id(desc.node_river_water)
		local b_riverbed = minetest.get_content_id(desc.node_riverbed)
		local b_riverbed_depth = desc.depth_riverbed or ""
		local b_cave_liquid = minetest.get_content_id(desc.node_cave_liquid)
		local b_dungeon = minetest.get_content_id(desc.node_dungeon)
		local b_dungeon_alt = minetest.get_content_id(desc.node_dungeon_alt)
		local b_dungeon_stair = minetest.get_content_id(desc.node_dungeon_stair)
		local b_node_dust = minetest.get_content_id(desc.node_dust)
		local b_miny = desc.y_min or ""
		local b_maxy = desc.y_max or ""
		local b_heat = desc.heat_point or ""
		local b_humid = desc.humidity_point or ""

		lib_mg_continental.biome_info[desc.name] = name .. "|" .. b_cid .. "|" .. b_top .. "|" .. b_top_depth .. "|" .. b_filler .. "|" .. b_filler_depth .. "|" .. b_stone .. "|" .. b_water_top
				.. "|" .. b_water_top_depth .. "|" .. b_water .. "|" .. b_river .. "|" .. b_riverbed .. "|" .. b_riverbed_depth .. "|" .. b_cave_liquid .. "|" .. b_dungeon
				.. "|" .. b_dungeon_alt .. "|" .. b_dungeon_stair .. "|" .. b_node_dust .. "|" .. b_miny .. "|" .. b_maxy .. "|" .. b_heat .. "|" .. b_humid .. "\n"

	end
end


local function make_voronoi(cells, size)

	if not cells or not size then
		return
	end

	-- Start time of voronoi generation.
	local t0 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Random Points generation start")

	--Prevents points from too near edges, ideally creating more evenly sized cells.
	--Minumum: 50
	local size_offset = 125
	local size_half = size / 2

	local t_map_cell = {}
	
	if cells > 0 then
		local temp_points = "#Index|Pos.Z|Pos.X\n"
		v_points = {}
		for i_c = 1, cells do
			local t_pt = {x = (math.random(1 + size_offset, size - size_offset) - size_half), z = (math.random(1 + size_offset, size - size_offset) - size_half)}
			v_points[i_c] = t_pt
			temp_points = temp_points .. i_c .. "|" .. t_pt.z .. "|" .. t_pt.x .. "\n"
		end
		lib_mg_continental.save_csv(temp_points, "lib_mg_continental_data_points.txt")
		minetest.log("[lib_mg_continental_voronoi] Voronoi Cell Point List:\n" .. temp_points .. "")
	elseif cells == 0 then
		v_points = {}
		for i, point in ipairs(mg_custom_data.base_points) do
			local idx, p_z, p_x = unpack(point)
			local t_pt = {x = tonumber(p_x), z = tonumber(p_z)}
			v_points[tonumber(idx)] = t_pt
		end
		minetest.log("[lib_mg_continental_voronoi] Voronoi Cell Point List loaded from file.")
	else
		
	end

	-- Random Points generation finished. Check the timer to know the elapsed time.
	local t1 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Random Points generation time " .. (t1-t0) .. " ms")
	minetest.log("[lib_mg_continental_voronoi] Cell Data (Cells, Neighbors, Midpoints) generation start")

	local temp_cells = "#Index|LinkIdx|Pos.Z|Pos.X|ClosestIndex|ClosestPosZ|ClosestPosX\n"
	local temp_neighbors = "#CellIndex|LinkIdx|CellPosZ|CellPosX|ClosestNeighborIndex|ClosestNeighborPosZ|ClosestNeighborPosX|ClosestNeighborDist|ClosestNeighborEDist|ClosestNeighborMDist|ClosestNeighborADist|NeighborMidPosZ|NeighborMidPosX\n"
	local temp_midpoints = "#LinkIdx|Pos.Z|Pos.X|DistBetweenCells|Cell1Idx|Cell1Dist|Cell2Idx|Cell2Dist|\n"

	for i, pos in pairs(v_points) do

		local closest_neighbor_idx = 0
		local closest_neighbor_pos_x = 0
		local closest_neighbor_pos_z = 0
		local closest_dist = 0			--chebyshev
		local closest_edist = 0			--euclidean
		local closest_adist = 0			--average
		local closest_mdist = 0			--manhattan
		local e_dist
		local m_dist
		local a_dist
		local s_dist
		local t_dist
		--local t_point_x, t_point_z

		for k, pt in pairs(v_points) do
			if i ~= k then
				local neighbor_add = false
				e_dist = get_euclid_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				--t_dist = get_euclidean2_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				t_dist = get_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				m_dist = get_manhattan_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				a_dist = get_avg_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				if s_dist then
					if s_dist > t_dist then
						s_dist = t_dist
						closest_neighbor_idx = k
						closest_neighbor_pos_x = pt.x
						closest_neighbor_pos_z = pt.z
						closest_dist = t_dist
						closest_edist = e_dist
						closest_mdist = m_dist
						closest_adist = a_dist
						neighbor_add = true
					elseif s_dist == t_dist then
						s_dist = t_dist
						closest_neighbor_idx = 0
						closest_neighbor_pos_x = pt.x
						closest_neighbor_pos_z = pt.z
						closest_dist = t_dist
					end
				else
					s_dist = t_dist
					closest_neighbor_idx = k
					closest_neighbor_pos_x = pt.x
					closest_neighbor_pos_z = pt.z
			
				end

				local m_point_x, m_point_z = get_midpoint({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
				temp_midpoints = temp_midpoints .. i .. "-" .. k .. "|" .. m_point_z .. "|" .. m_point_x .. "|" .. get_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z}) .. "|" .. i .. "|" .. get_distance({x=m_point_x,y=m_point_z}, {x=pos.x,y=pos.z}) .. "|" .. k .. "|" .. get_distance({x=pt.x,y=pt.z}, {x=m_point_x,y=m_point_z}) .. "\n"

				if neighbor_add == true then
					local t_point_x, t_point_z = get_midpoint({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
					temp_neighbors = temp_neighbors .. i .. "|" .. i .. "-" .. closest_neighbor_idx .. "|" .. pos.z .. "|" .. pos.x .. "|" .. closest_neighbor_idx .. "|" .. closest_neighbor_pos_z .. "|" .. closest_neighbor_pos_x .. "|" .. s_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. t_point_z .. "|" .. t_point_x .. "\n"
				end
			
			end

		end

		t_map_cell[i] = {
			link_idx = i .. "-" .. closest_neighbor_idx,
			z = pos.z,
			x = pos.x,
			closest_idx = closest_neighbor_idx,
			closestposz = closest_neighbor_pos_z,
			closestposx = closest_neighbor_pos_x,
		}
		temp_cells = temp_cells .. i .. "|" .. i .. "-" .. closest_neighbor_idx .. "|" .. pos.z .. "|" .. pos.x .. "|" .. closest_neighbor_idx .. "|" .. closest_neighbor_pos_z .. "|" .. closest_neighbor_pos_x .. "\n"

	end

	-- Random cell generation finished. Check the timer to know the elapsed time.
	local t2 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Cell Data (Cells, Neighbors, Midpoints) generation time " .. (t2-t1) .. " ms")

	lib_mg_continental.save_csv(temp_cells, "lib_mg_continental_data_cells.txt")
	lib_mg_continental.save_csv(temp_neighbors, "lib_mg_continental_data_neighbors.txt")
	lib_mg_continental.save_csv(temp_midpoints, "lib_mg_continental_data_midpoints.txt")

	-- Random cell generation finished. Check the timer to know the elapsed time.
	local t3 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Cell Data save time " .. (t3-t2) .. " ms")

	-- Print generation time of this mapchunk.
	local chugent = math.ceil((os.clock() - t0) * 1000)
	minetest.log("[lib_mg_continental_voronoi] Voronoi Data generation time " .. chugent .. " ms")

	--return t_map_cell
	return t_map_cell, temp_midpoints, temp_neighbors						--, temp_points

end

local function make_edge_map(size)

	-- Start time of voronoi generation.
	local t0 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Edge Map generation start")

	local t_map_edge = {}

	local temp_edges = "#ID|Index|Pos.Z|Pos.X|Cell1 Index|Cell1 Distance|Cell1 EDistance|Cell1 MDistance|Cell1 ADistance|Cell Index|Cell2 Distance|Cell2 EDistance|Cell2 MDistance|Cell2 ADistance\n"

	local idx = 1
	for i_z = (1-(size/2)), (size-(size/2)) do
		t_map_edge[i_z] = {}
		for i_x = (1-(size/2)), (size-(size/2)) do
			local closest_cell_idx = 0
			local closest_cell_dist
			local closest_cell_edist = 0
			local closest_cell_mdist = 0
			local closest_cell_adist = 0
			local last_closest_idx = 0
			local last_dist
			local this_dist
			local last_edist
			local last_mdist
			local last_adist
			local e_dist
			local m_dist
			local a_dist

			for i, pos in pairs(v_points) do

				local edge_add = false

				e_dist = get_euclid_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				--this_dist = get_euclidean2_distance({{x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				this_dist = get_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				m_dist = get_manhattan_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				a_dist = get_avg_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})

				if last_dist then
					if last_dist > this_dist then

						closest_cell_idx = i
						closest_cell_dist = this_dist
						closest_cell_edist = e_dist
						last_dist = this_dist
						last_edist = e_dist
						last_mdist = m_dist
						last_adist = a_dist
						last_closest_idx = i

					elseif last_dist == this_dist then

						closest_cell_idx = 0
						edge_add = true
					end
				else
					closest_cell_idx = i
					closest_cell_dist = this_dist
					closest_cell_edist = e_dist
					last_dist = this_dist
					last_edist = e_dist
					last_mdist = m_dist
					last_adist = a_dist
					last_closest_idx = i
				end

				if edge_add == true then
					t_map_edge[i_z][i_x] = {
						index = idx,
						cells_index = "" .. i .. "-" .. last_closest_idx .. "",
						cell1_index = i,
						cell1_distance = this_dist,
						cell1_edistance = e_dist,
						cell1_mdistance = m_dist,
						cell1_adistance = a_dist,
						cell2_index = last_closest_idx,
						cell2_distance = last_dist,
						cell2_edistance = last_edist,
						cell2_mdistance = last_mdist,
						cell2_adistance = last_adist,
					}
					temp_edges = temp_edges .. i_z .. "|" .. i_x .. "|" .. idx .. "|" .. i .. "-" .. last_closest_idx .. "|" .. i .. "|" .. this_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. last_closest_idx .. "|" .. last_dist .. "|" .. last_edist .. "|" .. last_mdist .. "|" .. last_adist .. "\n"
				end
			end

			idx = idx + 1
		end

	end

	local t1 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Edge Map generation time " .. (t1-t0) .. " ms")

	lib_mg_continental.save_csv(temp_edges, "lib_mg_continental_data_edges.txt")

	local t2 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Edge Map save time " .. (t2-t1) .. " ms")

	-- Print generation time of this mapchunk.
	local chugent = math.ceil((os.clock() - t0) * 1000)
	minetest.log("[lib_mg_continental_voronoi] Edge Map Total generation time " .. chugent .. " ms")

	return t_map_edge

end

local function make_voronoi_maps(size)

	-- Start time of voronoi generation.
	local t0 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps generation start")

	local t_map_voronoi = {}
	local t_map_edge = {}

	local temp_voronoi = "#Index|Pos.Z|Pos.X|ClosestIndex|ClosestDistance\n"
	local temp_edges = "#ID|Index|Pos.Z|Pos.X|Cell1 Index|Cell1 Distance|Cell1 EDistance|Cell1 MDistance|Cell1 ADistance|Cell Index|Cell2 Distance|Cell2 EDistance|Cell2 MDistance|Cell2 ADistance\n"

	local idx = 1
	for i_z = (1-(size/2)), (size-(size/2)) do
		t_map_voronoi[i_z] = {}
		t_map_edge[i_z] = {}
		for i_x = (1-(size/2)), (size-(size/2)) do
			local closest_cell_idx = 0
			local closest_cell_dist
			local closest_cell_edist = 0
			local closest_cell_mdist = 0
			local closest_cell_adist = 0
			local last_closest_idx = 0
			local last_dist
			local this_dist
			local last_edist
			local last_mdist
			local last_adist
			local e_dist
			local m_dist
			local a_dist

			for i, pos in pairs(v_points) do

				local edge_add = false

				e_dist = get_euclid_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				--this_dist = get_euclidean2_distance({{x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				this_dist = get_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				m_dist = get_manhattan_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
				a_dist = get_avg_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})

				if last_dist then
					if last_dist > this_dist then

						closest_cell_idx = i
						closest_cell_dist = this_dist
						closest_cell_edist = e_dist
						last_dist = this_dist
						last_edist = e_dist
						last_mdist = m_dist
						last_adist = a_dist
						last_closest_idx = i

					elseif last_dist == this_dist then

						closest_cell_idx = 0
						edge_add = true
					end
				else
					closest_cell_idx = i
					closest_cell_dist = this_dist
					closest_cell_edist = e_dist
					last_dist = this_dist
					last_edist = e_dist
					last_mdist = m_dist
					last_adist = a_dist
					last_closest_idx = i
				end

				if edge_add == true then
					t_map_edge[i_z][i_x] = {
						index = "" .. i .. "-" .. last_closest_idx .. "",
						z = i_z,
						x = i_x,
						cell1_index = i,
						cell1_distance = this_dist,
						cell1_edistance = e_dist,
						cell1_mdistance = m_dist,
						cell1_adistance = a_dist,
						cell2_index = last_closest_idx,
						cell2_distance = last_dist,
						cell2_edistance = last_edist,
						cell2_mdistance = last_mdist,
						cell2_adistance = last_adist,
					}
					temp_edges = temp_edges .. idx .. "|" .. i .. "-" .. last_closest_idx .. "|" .. i_z .. "|" .. i_x .. "|" .. i .. "|" .. this_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. last_closest_idx .. "|" .. last_dist .. "|" .. last_edist .. "|" .. last_mdist .. "|" .. last_adist .. "\n"
				end
			end

			t_map_voronoi[i_z][i_x] = {
				closest_idx = closest_cell_idx,
				closest_dist = closest_cell_dist,
				closest_edist = closest_cell_edist,
				closest_mdist = closest_cell_mdist,
				closest_adist = closest_cell_adist,
			}
			--temp_voronoi = temp_voronoi .. i_z .. "|" .. i_x .. "|" .. closest_cell_idx .. "|" .. closest_cell_dist .. "\n"
			idx = idx + 1
		end

	end

	local t1 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps generation time " .. (t1-t0) .. " ms")

	--lib_mg_continental.save_csv(temp_voronoi, "lib_mg_continental_data_voronoi.txt")
	lib_mg_continental.save_csv(temp_edges, "lib_mg_continental_data_edges.txt")

	local t2 = os.clock()
	minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps save time " .. (t2-t1) .. " ms")

	-- Print generation time of this mapchunk.
	local chugent = math.ceil((os.clock() - t0) * 1000)
	minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps Total generation time " .. chugent .. " ms")

	return t_map_voronoi, t_map_edge
	--return t_map_voronoi, temp_edges

end

minetest.log("[lib_mg_continental_mg_dev_voronoi] Custom Data Load / Gen Start")
mg_custom_data.base_points = lib_mg_continental.load_csv("|", "lib_mg_continental_data_points.txt")
mg_custom_data.base_cells = lib_mg_continental.load_csv("|", "lib_mg_continental_data_cells.txt")
mg_custom_data.base_cellmap = lib_mg_continental.load("lib_mg_continental_data_cellmap.txt")
mg_custom_data.base_midpoints = lib_mg_continental.load_csv("|", "lib_mg_continental_data_midpoints.txt")
mg_custom_data.base_tectonicmap = lib_mg_continental.load("lib_mg_continental_data_tectonicmap.txt")
mg_custom_data.base_edgemap = lib_mg_continental.load("lib_mg_continental_data_edgemap.txt")
--mg_custom_data.base_edgemap = lib_mg_continental.load_csv("|", "lib_mg_continental_data_edges.txt")

if not (mg_custom_data.base_cellmap) then
	if (mg_custom_data.base_midpoints == nil) then
		if (mg_custom_data.base_points == nil) then
			mg_custom_data.base_cellmap, mg_custom_data.base_midpoints, mg_custom_data.base_neighbors = make_voronoi(voronoi_cells, map_scale)
			lib_mg_continental.save(mg_custom_data.base_cellmap, "lib_mg_continental_data_cellmap.txt")
		else
			mg_custom_data.base_cellmap, mg_custom_data.base_midpoints, mg_custom_data.base_neighbors = make_voronoi(0, map_scale)
			lib_mg_continental.save(mg_custom_data.base_cellmap, "lib_mg_continental_data_cellmap.txt")
		end
	end
end
if not (mg_custom_data.base_tectonicmap) or not (mg_custom_data.base_edgemap) then
	mg_custom_data.base_tectonicmap, mg_custom_data.base_edgemap = make_voronoi_maps(map_scale)
	lib_mg_continental.save(mg_custom_data.base_tectonicmap, "lib_mg_continental_data_tectonicmap.txt")
	lib_mg_continental.save(mg_custom_data.base_edgemap, "lib_mg_continental_data_edgemap.txt")
end
minetest.log("[lib_mg_continental_voronoi] Custom Data Load / Gen End")

local mapgen_times = {
	liquid_lighting = {},
	loops = {},
	make_chunk = {},
	noisemaps = {},
	preparation = {},
	writing = {},
}

local data = {}

minetest.register_on_generated(function(minp, maxp, seed)
	
	-- Start time of mapchunk generation.
	local t0 = os.clock()
	
	--ShadMOrdre
	local x1 = maxp.x
	local y1 = maxp.y
	local z1 = maxp.z
	local x0 = minp.x
	local y0 = minp.y
	local z0 = minp.z
	--
	
	local sidelen = maxp.x - minp.x + 1
	local permapdims3d = {x = sidelen, y = sidelen, z = 0}

	--ShadMOrdre
	local overlen = sidelen + 5
	local chulens = {x = overlen, y = overlen, z = 1}
	local minpos  = {x = x0 - 3, y = z0 - 3}
	--

	local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
	data = vm:get_data()
	local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
	local csize = vector.add(vector.subtract(maxp, minp), 1)
	
	nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, csize)
	--nbase_terrain = nobj_terrain:get2dMap_flat({x=minp.x, y=minp.z})
	isln_terrain=nobj_terrain:get_2d_map({x=minp.x,y=minp.z})

	---- cliffs
	nobj_cliffs = nobj_cliffs or minetest.get_perlin_map(np_cliffs, permapdims3d)
	isln_cliffs = nobj_cliffs:get_2d_map({x=minp.x,y=minp.z})

	nobj_heatmap = nobj_heatmap or minetest.get_perlin_map(np_heat, chulens)
	nbase_heatmap = nobj_heatmap:get2dMap_flat({x=minp.x, y=minp.z})
	nobj_heatblend = nobj_heatblend or minetest.get_perlin_map(np_heat_blend, chulens)
	nbase_heatblend = nobj_heatblend:get2dMap_flat({x=minp.x, y=minp.z})
	nobj_humiditymap = nobj_humiditymap or minetest.get_perlin_map(np_humid, chulens)
	nbase_humiditymap = nobj_humiditymap:get2dMap_flat({x=minp.x, y=minp.z})
	nobj_humidityblend = nobj_humidityblend or minetest.get_perlin_map(np_humid_blend, chulens)
	nbase_humidityblend = nobj_humidityblend:get2dMap_flat({x=minp.x, y=minp.z})

	-- Mapgen preparation is now finished. Check the timer to know the elapsed time.
	local t1 = os.clock()

	local write = false
	
-- 2D Generation loop.
	local index2d = 0
	for z = minp.z, maxp.z do
		for x = minp.x, maxp.x do

			index2d = (z - minp.z) * csize.x + (x - minp.x) + 1

--2D HEIGHTMAP GENERATION
			local s_z, s_z_r
			local s_x, s_x_r

			local theight
			local ntectonic_idx
			local ntectonic_dist
			local ntectonic_edist
			--local ntectonic_mist
			--local ntectonic_aist

			if mg_map_view == false then
				s_z, s_z_r = math.modf(z / map_tectonic_scale)
				s_x, s_x_r = math.modf(x / map_tectonic_scale)
				if s_z_r >= 5 then
					s_z = s_z + 1
				end
				if s_x_r >= 5 then
					s_x = s_x + 1
				end
				ntectonic_idx = mg_custom_data.base_tectonicmap[s_z][s_x].closest_idx
				ntectonic_dist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_dist
				ntectonic_edist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_edist
				--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
				--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
			else
				s_z = z
				s_x = x
				if ((z > -500) and (z < 500)) and ((x > -500) and (x < 500)) then
					ntectonic_idx = mg_custom_data.base_tectonicmap[z][x].closest_idx
					ntectonic_dist = mg_custom_data.base_tectonicmap[z][x].closest_dist
					ntectonic_edist = mg_custom_data.base_tectonicmap[z][x].closest_edist
					--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
					--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
				else
					ntectonic_idx = -1234
					ntectonic_dist = -2
					ntectonic_edist = -2
				end
			end

--
			if mg_map_view == false then
				if ntectonic_idx <= 0 then
	
					local cell1_idx
					local cell1_pos_x
					local cell1_pos_z
					local cell2_idx
					local cell2_pos_x
					local cell2_pos_z
	
					cell1_idx = mg_custom_data.base_edgemap[s_z][s_x].cell1_index
					cell2_idx = mg_custom_data.base_edgemap[s_z][s_x].cell2_index
		
					cell1_pos_x = mg_custom_data.base_cellmap[cell1_idx].x * map_tectonic_scale
					cell1_pos_z = mg_custom_data.base_cellmap[cell1_idx].z * map_tectonic_scale
					cell2_pos_x = mg_custom_data.base_cellmap[cell2_idx].x * map_tectonic_scale
					cell2_pos_z = mg_custom_data.base_cellmap[cell2_idx].z * map_tectonic_scale
		
					local cell1_dist = get_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
					local cell1_edist = get_euclid_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
					local cell2_dist = get_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
					local cell2_edist = get_euclid_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
	
					if cell1_dist == cell2_dist then
						ntectonic_idx = 0
						--ntectonic_dist = cell1_dist
						--if cell1_edist > cell2_edist then
						--	ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
						--elseif cell1_edist < cell2_edist then
						--	ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
						--end
					elseif cell1_dist > cell2_dist then
						ntectonic_idx = cell2_idx
						--ntectonic_dist = cell2_dist
						--if cell1_edist > cell2_edist then
						--	ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
						--elseif cell1_edist < cell2_edist then
						--	ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
						--end
					else
						ntectonic_idx = cell1_idx
						--ntectonic_dist = cell1_dist
						--if cell1_edist > cell2_edist then
						--	ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
						--elseif cell1_edist < cell2_edist then
						--	ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
						--end
					end
				end
--
			end

			local ntectonic_rdist = (ntectonic_dist + ntectonic_edist) * 0.5		--ridges

			local ntect_dist, ntect_dist_r = math.modf(ntectonic_dist * 0.1)
			local ntect_edist, ntect_edist_r = math.modf(ntectonic_edist * 0.1)
			--local ntect_mdist, ntect_mdist_r = math.modf(ntectonic_mdist * 0.1)
			--local ntect_adist, ntect_adist_r = math.modf(ntectonic_adist * 0.1)
			local ntect_rdist, ntect_rdist_r = math.modf(ntectonic_rdist * 0.1)

			local nterrain = isln_terrain[z-minp.z+1][x-minp.x+1]
			local cheight = isln_cliffs[z-minp.z+1][x-minp.x+1]

			local ncontinental = get_terrain_height_shelf(ntectonic_edist) * -0.1
			local nmountain = (get_terrain_height_shelf(ntectonic_rdist) * 0.1) - 2

			if mg_map_view == false then
				theight = get_terrain_height_hills_adjustable_shelf(nterrain + (math.max(ncontinental,nmountain)*0.5),(math.max(ncontinental,nmountain)*0.1),cheight,(ntect_rdist + (ntect_rdist / mg_golden_ratio))) - 2
			else
				theight = get_terrain_height_hills_adjustable_shelf(nterrain + (nmountain * 0.1),(nmountain * 0.1),cheight,(ntect_rdist + (ntect_rdist / mg_golden_ratio)) * 0.1) + 3
			end
	
			lib_mg_continental.heightmap[index2d] = theight - 1

		end
	end

--2D HEIGHTMAP GENERATION
	local index2d = 0
	--local idx = 1
	for z = minp.z, maxp.z do
		for y = minp.y, maxp.y do
			for x = minp.x, maxp.x do
			 
				index2d = (z - minp.z) * csize.x + (x - minp.x) + 1   
				local ivm = a:index(x, y, z)

				local theight = lib_mg_continental.heightmap[index2d]

				if y <= theight + 1 then

					local t_heat, t_humid, t_altitude, t_name
	
					local nheat = nbase_heatmap[index2d] + nbase_heatblend[index2d]
					local nhumid = nbase_humiditymap[index2d] + nbase_humidityblend[index2d]
	
					if nheat < 12.5 then
						t_heat = "cold"
					elseif nheat >= 12.5 and nheat < 37.5 then
						t_heat = "cool"
					elseif nheat >= 37.5 and nheat < 62.5 then
						t_heat = "temperate"
					elseif nheat >= 62.5 and nheat < 87.5 then
						t_heat = "warm"
					elseif nheat >= 87.5 then
						t_heat = "hot"
					else
						--t_heat = ""
					end
			
					if nhumid < 12.5 then
						t_humid = "arid"
					elseif nhumid >= 12.5 and nhumid < 37.5 then
						t_humid = "semiarid"
					elseif nhumid >= 37.5 and nhumid < 62.5 then
						t_humid = "temperate"
					elseif nhumid >= 62.5 and nhumid < 87.5 then
						t_humid = "semihumid"
					elseif nhumid >= 87.5 then
						t_humid = "humid"
					else
						--t_humid = ""
					end
			
					if y >= lib_materials.ocean_depth and y < lib_materials.beach_depth then
						t_altitude = "ocean"
					elseif y >= lib_materials.beach_depth and y < lib_materials.maxheight_beach then
						t_altitude = "beach"
					elseif y >= lib_materials.maxheight_beach and y < lib_materials.maxheight_coastal then
						t_altitude = "coastal"
					elseif y >= lib_materials.maxheight_coastal and y < lib_materials.maxheight_lowland then
						t_altitude = "lowland"
					elseif y >= lib_materials.maxheight_lowland and y < lib_materials.maxheight_shelf then
						t_altitude = "shelf"
					elseif y >= lib_materials.maxheight_shelf and y < lib_materials.maxheight_highland then
						t_altitude = "highland"
					elseif y >= lib_materials.maxheight_highland and y < lib_materials.maxheight_mountain then
						t_altitude = "mountain"
					elseif y >= lib_materials.maxheight_mountain and y < lib_materials.maxheight_strato then
						t_altitude = "strato"
					else
						--t_altitude = ""
					end
	
					if t_heat and t_heat ~= "" and t_humid and t_humid ~= ""  and t_altitude and t_altitude ~= "" then
						t_name = t_heat .. "_" .. t_humid .. "_" .. t_altitude
					end
	
					if y >= -31000 and y < -20000 then
						t_name = "generic_mantle"
					elseif y >= -20000 and y < -15000 then
						t_name = "stone_basalt_01_layer"
					elseif y >= -15000 and y < -10000 then
						t_name = "stone_brown_layer"
					elseif y >= -10000 and y < -6000 then
						t_name = "stone_sand_layer"
					elseif y >= -6000 and y < -5000 then
						t_name = "desert_stone_layer"
					elseif y >= -5000 and y < -4000 then
						t_name = "desert_sandstone_layer"
					elseif y >= -4000 and y < -3000 then
						t_name = "generic_stone_limestone_01_layer"
					elseif y >= -3000 and y < -2000 then
						t_name = "generic_granite_layer"
					elseif y >= -2000 and y < lib_materials.ocean_depth then
						t_name = "generic_stone_layer"
					else
						
					end
			
					local b_name, b_cid, b_top, b_top_d, b_fill, b_fill_d, b_stone, b_water_top, b_water_top_d, b_water, b_river, b_riverbed, b_riverbed_d
					local b_caveliquid, b_dungeon, b_dungeonalt, b_dungeonstair, b_dust, b_ymin, b_ymax, b_heat, b_humid
			
					if t_name == "" then
						t_name = minetest.get_biome_name(minetest.get_biome_data({x,y,z}).biome)
					end
	
					local fill_depth = 1
					local top_depth = 1
	
					if t_name and t_name ~= "" then
	
						b_name, b_cid, b_top, b_top_d, b_fill, b_fill_d, b_stone, b_water_top, b_water_top_d, b_water, b_river, b_riverbed, b_riverbed_d, b_caveliquid, b_dungeon, b_dungeonalt, b_dungeonstair, b_dust, b_ymin, b_ymax, b_heat, b_humid = unpack(lib_mg_continental.biome_info[t_name]:split("|", false))
	
						c_stone = b_stone
						c_dirt = b_fill
						fill_depth = b_fill_d or 6
						c_top = b_top
						top_depth = b_top_d or 1
	
					end
					lib_mg_continental.biomemap[index2d] = b_cid

--VORONOI MARKERS FROM TECTONICMAP
					local s_z, s_z_r
					local s_x, s_x_r
		
					local ntectonic_idx
					local ntectonic_dist
					--local ntectonic_eist
					--local ntectonic_mist
					--local ntectonic_aist
		
					if mg_map_view == false then
						s_z, s_z_r = math.modf(z / map_tectonic_scale)
						s_x, s_x_r = math.modf(x / map_tectonic_scale)
						if s_z_r >= 5 then
							s_z = s_z + 1
						end
						if s_x_r >= 5 then
							s_x = s_x + 1
						end
						ntectonic_idx = mg_custom_data.base_tectonicmap[s_z][s_x].closest_idx
						ntectonic_dist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_dist
						--ntectonic_edist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_edist
						--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
						--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
					else
						s_z = z
						s_x = x
						if ((z > -500) and (z < 500)) and ((x > -500) and (x < 500)) then
							ntectonic_idx = mg_custom_data.base_tectonicmap[z][x].closest_idx
							ntectonic_dist = mg_custom_data.base_tectonicmap[z][x].closest_dist
							ntectonic_edist = mg_custom_data.base_tectonicmap[z][x].closest_edist
						else
							ntectonic_idx = -1234
							ntectonic_dist = -2
							ntectonic_edist = -2
						end
					end
	
					if ntectonic_dist == 0 then

						c_top = c_obsidian

					end

					if mg_map_view == false then
						if ntectonic_idx <= 0 then
			
							local cell1_idx
							local cell1_pos_x
							local cell1_pos_z
							local cell2_idx
							local cell2_pos_x
							local cell2_pos_z
			
							cell1_idx = mg_custom_data.base_edgemap[s_z][s_x].cell1_index
							cell2_idx = mg_custom_data.base_edgemap[s_z][s_x].cell2_index
				
							cell1_pos_x = mg_custom_data.base_cellmap[cell1_idx].x * map_tectonic_scale
							cell1_pos_z = mg_custom_data.base_cellmap[cell1_idx].z * map_tectonic_scale
							cell2_pos_x = mg_custom_data.base_cellmap[cell2_idx].x * map_tectonic_scale
							cell2_pos_z = mg_custom_data.base_cellmap[cell2_idx].z * map_tectonic_scale
				
							local cell1_dist = get_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
							local cell1_edist = get_euclid_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
							local cell2_dist = get_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
							local cell2_edist = get_euclid_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
			
							if cell1_dist == cell2_dist then
								ntectonic_idx = 0
								ntectonic_dist = cell1_dist
								ntectonic_edist = cell1_edist
								c_top = c_obsidian
							elseif cell1_dist > cell2_dist then
								ntectonic_idx = cell2_idx
								ntectonic_dist = cell2_dist
								ntectonic_edist = cell2_edist
							else
								ntectonic_idx = cell1_idx
								ntectonic_dist = cell1_dist
								ntectonic_edist = cell1_edist
							end
						end
					end
				end

--NODE PLACEMENT FROM HEIGHTMAP
	
				if y < (theight - (fill_depth + top_depth)) then
					data[ivm] = c_stone
					write = true
				elseif y >= (theight - (fill_depth + top_depth)) and y < (theight - top_depth) then					--math.ceil(nobj_terrain[index2d])
					data[ivm] = c_dirt
					write = true
				elseif y >= (theight - top_depth) and y <= theight then					--math.ceil(nobj_terrain[index2d])
					data[ivm] = c_top
					write = true
				elseif y > theight and y <= 1 then
					data[ivm] = c_water
					write = true
				else
					data[ivm] = c_air
					write = true
				end


			end
		end
	end
	
	local t2 = os.clock()

	if write then
		vm:set_data(data)
	end

	local t3 = os.clock()
	
	if write then

		minetest.generate_ores(vm,minp,maxp)
		minetest.generate_decorations(vm,minp,maxp)
			
		vm:set_lighting({day = 0, night = 0})
		vm:calc_lighting()
		vm:update_liquids()
	end

	local t4 = os.clock()

	if write then
		vm:write_to_map()
	end

	local t5 = os.clock()

	-- Print generation time of this mapchunk.
	local chugent = math.ceil((os.clock() - t0) * 1000)
	print ("[lib_mg_continental_mg_custom_biomes] Mapchunk generation time " .. chugent .. " ms")

	table.insert(mapgen_times.noisemaps, 0)
	table.insert(mapgen_times.preparation, t1 - t0)
	table.insert(mapgen_times.loops, t2 - t1)
	table.insert(mapgen_times.writing, t3 - t2 + t5 - t4)
	table.insert(mapgen_times.liquid_lighting, t4 - t3)
	table.insert(mapgen_times.make_chunk, t5 - t0)

	-- Deal with memory issues. This, of course, is supposed to be automatic.
	local mem = math.floor(collectgarbage("count")/1024)
	if mem > 1000 then
		print("lib_mg_continental_mg_custom_biomes is manually collecting garbage as memory use has exceeded 500K.")
		collectgarbage("collect")
	end
end)

local function mean( t )
	local sum = 0
	local count= 0

	for k,v in pairs(t) do
		if type(v) == 'number' then
			sum = sum + v
			count = count + 1
		end
	end

	return (sum / count)
end

minetest.register_on_shutdown(function()
	if #mapgen_times.make_chunk == 0 then
		return
	end

	local average, standard_dev
	minetest.log("lib_mg_continental_mg_custom_biomes lua Mapgen Times:")

	average = mean(mapgen_times.liquid_lighting)
	minetest.log("  liquid_lighting: - - - - - - - - - - - -  "..average)

	average = mean(mapgen_times.loops)
	minetest.log("  loops: - - - - - - - - - - - - - - - - -  "..average)

	average = mean(mapgen_times.make_chunk)
	minetest.log("  makeChunk: - - - - - - - - - - - - - - -  "..average)

	average = mean(mapgen_times.noisemaps)
	minetest.log("  noisemaps: - - - - - - - - - - - - - - -  "..average)

	average = mean(mapgen_times.preparation)
	minetest.log("  preparation: - - - - - - - - - - - - - -  "..average)

	average = mean(mapgen_times.writing)
	minetest.log("  writing: - - - - - - - - - - - - - - - -  "..average)
end)

minetest.register_on_newplayer(function(obj)

	local nobj_terrain = minetest.get_perlin_map(np_terrain, {x=1,y=1,z=0})	
	local th=nobj_terrain:get_2d_map({x=1,y=1})
	local height = 0

	local ntect_idx = mg_custom_data.base_tectonicmap[0][0].closest_idx
	local ntect_dist = mg_custom_data.base_tectonicmap[0][0].closest_dist

	if ntect_dist == 0 then
		ntect_dist = 1
	end
	height = ntect_dist / th[1][1]

	minetest.set_timeofday(0.30)

	return true
end)




User avatar
Grigor
Member
Posts: 49
Joined: Sun Dec 01, 2019 05:55

Re: Post your mapgen questions here (modding or engine)

by Grigor » Post

Hi all, hope you're all coping with the Current World Situation.

Question re V7 map - the trees all sit 1 node below ground level, where in V6 they sit ON ground level. Not an issue unless you're using Round Trunks, then things start to look a little untidy.

Is there a simple way to move all the trees up by 1 node in the generation of the map?

User avatar
Skamiz Kazzarch
Member
Posts: 613
Joined: Fri Mar 09, 2018 20:34
GitHub: Skamiz
In-game: Skamiz
Location: la lojbaugag.

Re: Post your mapgen questions here (modding or engine)

by Skamiz Kazzarch » Post

The simplest I can think of is going to the decoration definition and adding: 'place_offset_y = 1,'
The tree decoration deffinitions can be found in "your_minetest_folder/games/minetest_game/mods/default/magen.lua" and begin at line 1815.
If you want to know more about how decorations are registered, here is the documentation:
https://github.com/minetest/minetest/bl ... .txt#L7585

User avatar
paramat
Developer
Posts: 3700
Joined: Sun Oct 28, 2012 00:05
GitHub: paramat
IRC: paramat
Location: UK

Re: Post your mapgen questions here (modding or engine)

by paramat » Post

> The simplest I can think of is going to the decoration definition and adding: 'place_offset_y = 1,'

This.

User avatar
Grigor
Member
Posts: 49
Joined: Sun Dec 01, 2019 05:55

Re: Post your mapgen questions here (modding or engine)

by Grigor » Post

Thanks guys. I think I was trying place_offset_y + 1, and it took exception to the +. Will try this out.

Take care, y'all!

Kurtzmusch
Member
Posts: 41
Joined: Sat Oct 21, 2017 18:12
In-game: Kurtzmusch

Re: Post your mapgen questions here (modding or engine)

by Kurtzmusch » Post

is it possible to obtain a vmanip of an area that hasnt been emerged or generated yet? if yes, will the singlenode mapgen eventually overwrite it with air?
Like Puzzles? Escape The Dungeon

User avatar
acidzebra
Member
Posts: 75
Joined: Sun Sep 10, 2017 09:11

Re: Post your mapgen questions here (modding or engine)

by acidzebra » Post

Mod A has a custom lua mapgen.
Mod B depends on mod A and defines schematic type decorations to be placed on nodes added by mod A.

No errors, mod A generates terrain just fine, but the schematics are never placed.

I checked that the right nodes are referenced, I've tried various things and the schematics are placed just fine in the default mapgen using default nodes, and I'm starting to think I'm missing something here.

Any idea?

edit: I guess I need to use https://dev.minetest.net/minetest.place ... _on_vmanip instead? Gonna try and wrap my head around that stuff.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests