New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Carpathian mapgen #6015
Add Carpathian mapgen #6015
Conversation
Nice! Screenshots? Bigger description? |
See forum post for some screenshots. Features:
|
|
||
struct MapgenCarpathianParams : public MapgenParams | ||
{ | ||
u32 spflags = MGCARPATHIAN_CAVERNS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice ! C++11 constructor :D
src/mapgen.h
Outdated
@@ -114,6 +114,7 @@ enum MapgenType { | |||
MAPGEN_V5, | |||
MAPGEN_V6, | |||
MAPGEN_V7, | |||
MAPGEN_CARPATHIAN, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if i remember this enum should be ordered by mapgen addition instead of names, @paramat can you confirm ?
It prevents mapgen ID mismatch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This enum was created in this form in hmmmm's mapgen reorganisation commit 9270530
So i'm sure it's fine as it is.
However any new mapgens should perhaps be added after 'invalid', not sure if that is essential but seems the safest thing to do with an enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the enum to this order:
enum MapgenType { MAPGEN_V5, MAPGEN_V6, MAPGEN_V7, MAPGEN_FLAT, MAPGEN_FRACTAL, MAPGEN_VALLEYS, MAPGEN_SINGLENODE, MAPGEN_INVALID, MAPGEN_CARPATHIAN, };
but it compiles with error:
/Users/vlapsley/games/minetest/src/mapgen.cpp:93:1: error: 'registered_mapgens_is_wrong_size'
declared as an array with a negative size
STATIC_ASSERT(
^~~~~~~~~~~~~~
/Users/vlapsley/games/minetest/src/util/basic_macros.h:50:36: note: expanded from macro
'STATIC_ASSERT'
UNUSED_ATTRIBUTE typedef char msg[!!(expr) * 2 - 1]
^~~~~~~~~~~~~~~~
1 error generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
STATIC_ASSERT(
ARRLEN(g_reg_mapgens) == MAPGEN_INVALID,
registered_mapgens_is_wrong_size);
Looks like 'invalid' needs to be the last one, so add it just before 'invalid'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah invalid should be last
I haven't seen your mapgen in the forums before, thus I'm very surprised and happy to see this PR. The code is well written - unlike what LINT (TravisCI) tries to suggest. Will check it out ASAP. |
I'll test of course. From the forum thread i see there are some nice mountain shapes. |
please migrate all your constructors to C++11 form (look at mapgenflat for example) |
@nerzhul Can you elaborate please? I thought I'd already migrated to C++11 constructors. Am I missing something else? |
I think i was fallen in my breakfast this morning... ignore my comment |
Nice |
Thanks, lint suggested some sensible fixes which you have done with good judgement while avoiding the unreasonable ones. |
You can silence the linter requests by adding the files to the whitelist here https://github.com/minetest/minetest/blob/master/util/travis/clang-format-whitelist.txt |
Please don't merge this until i have reviewed. |
raising the water level still seems to mess up the mapgen, is that impossible to fix? |
👍 |
|
water level isn't suppose to change the shape of the land scape right? |
|
This block of code is responsible for mess associated with changing the water level:
I did a quick test changing it to this:
A water level setting of 1 gives a terrain that's unchanged. But altering water level by a significant amount (I tried -10 and 10) produced different terrain results even with the code above. Maybe I missed something? I'll run some further tests to see I can fix this up. |
I see you're using a density gradient as in my 'watershed' mapgen and linking that to water_level, that makes sense because you alter the density gradient below water level to make seabed variation smaller. |
Wow, I must've eaten the wrong mushrooms. Those spotty red ones. ;) It seems I had edited the spawn point gradient and forgot to edit the terrain gradient as well. I've changed that and testing works well with a variable water level. Tested with water_level = 1, -10, -100, 10 and 50. Terrain now remains unaffected. |
thanks |
src/mapgen_carpathian.cpp
Outdated
this->cave_width = params->cave_width; | ||
this->cavern_limit = params->cavern_limit; | ||
this->cavern_taper = params->cavern_taper; | ||
this->cavern_threshold = params->cavern_threshold; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are using large pseudorandom caves 2 more parameters are needed to be able to shift those caves and the lava they contain vertically if terrain is shifted vertically, see mgv7:
this->large_cave_depth = params->large_cave_depth;
this->lava_depth = params->lava_depth;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can leave out lava_depth if you want as it has a default of y = -256, but only if terrain is locked to y = 1.
src/mapgen_carpathian.cpp
Outdated
// Lerp function | ||
float MapgenCarpathian::getLerp(float noise1, float noise2, float mod) | ||
{ | ||
return (1.f - mod) * noise1 + mod * noise2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mnt_var noise is:
+ np_mnt_var = NoiseParams(0, 1, v3f(499, 499, 499), 2490, 5, 0.6, 2.0);
in case you did not know, with scale 1 and 5 octaves persistence 0.6 the value will actually vary between roughly -2 and 2.
Specifically the variation will be 1 + 0.6 + 0.6^2 + 0.6^3 + 0.6^4.
So if you want you might prefer to limit mod
to -1 to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, when such limits are hit they can create 'edges' visible in the terrain. If you are happy with the current terrain no need to change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with the way it is. As you say, clamping the upper and lower limit will create edges.
I played with the noise, reducing scale and octaves separately, but I found some of my favourite features where the noise is amplified by two ranges meeting together lost its charm.
If a player wants to reduce the occasional craziness of some mountains, this is the noise parameter to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could speed up this function a bit:
- Inline
- One multiplication less:
return noise1 - mod * (noise1 + noise2)
We already have a similar, simplified function in the noise code but that one would be for(1 - mod)
src/mapgen_carpathian.cpp
Outdated
float w = fabs(noise2); | ||
float k = floor(noise1 / w); | ||
float f = (noise1 - k * w) / w; | ||
float s = fmin(2.f * f, 1.f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not essential but i was advised to use MTs builtin functions MYMIN() and MYMAX().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got no problem changing to MYMIN and MYMAX functions.
I was going to ask why use these functions over the cmath library, but I've just read that fmin/fmax were introduced in C++11 and may not work with older compilers.
So I will make the changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are using c++11 now so it's fine, leave it as it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, i was advised by hmmmm to use MYMIN/MYMAX but this was a while ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah its was at the era of non portable C++
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we use C++11, std::fmax
is probably the better choice - more a standard than our Minetest-specific MYMAX function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i will start to use std::fmain/std::fmax from now on.
src/mapgen_carpathian.cpp
Outdated
float ground = noise_base->result[index2d]; | ||
|
||
// Gradient | ||
int grad = (1 - y); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems here you are using y = 1 (sea level) as the grad zero point and compressing the terrain variation below sea level.
Sea level is actually variable using the global mapgen parameter water_level
so:
+ int grad = (water_level - y);
+ if (y < water_level) {
+ grad *= 3;
+ }
This must be why it was reported that changing water_level messes stuff up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll tell you one of my mapgen tricks.
If you add a vertical_scale
parameter, default 1, and do:
+ int grad = (water_level - y) / vertical_scale;
The parameter acts like a master control on terrain vertical scale, easily changed without editing many confusing noise parameters.
The main use for this is the following:
Set vertical_scale
to 0.1.
Divide all noise parameter 'spread' values (v3f(1889, 1889, 1889)
) by 10.
This shrinks the terrain by a factor of 10 both vertically and horizontally, creating a 1/10th scale 3D map of your mapgen. To create a map disable biomes, caves and decorations (clear the registered biomes in a mod).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial work did use a vertical_scale
parameter. But I had awful problems with worlds sometimes not spawning stone - only air and water.
Or, sometimes you would spawn in the ground and the ground (completely flat) would be at y=180 and mountains would be going up to y=400 or 500 and canyons down to water level. It was beautiful and wrong at the same time.
Perhaps I had something else incorrect in the code that caused this though.
Don't ask how many times I rewrote this mapgen from scratch. I'm still coding with learner-plates on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, i'm not asking for this to be included.
src/mapgen_carpathian.cpp
Outdated
float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed); | ||
|
||
// Grad at water_level | ||
int grad_wl = 1 - water_level; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s32 instead of int
grad_wl can be a private class member calculated once at line 63 in the .cpp constructor
src/mapgen_carpathian.cpp
Outdated
// Grad at water_level | ||
int grad_wl = 1 - water_level; | ||
// Gradient | ||
int grad = (1 - y); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s32 instead of int
no brackets
src/mapgen_carpathian.cpp
Outdated
// Gradient | ||
int grad = (1 - y); | ||
// Shallow seabed | ||
if (y < water_level) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since action is a single line no need for curly brackets
src/mapgen_carpathian.cpp
Outdated
float ground = noise_base->result[index2d]; | ||
|
||
// Grad at water_level | ||
int grad_wl = 1 - water_level; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s32 instead of int
grad_wl can be a private class member calculated once at line 63 in the .cpp constructor
src/mapgen_carpathian.cpp
Outdated
// Grad at water_level | ||
int grad_wl = 1 - water_level; | ||
// Gradient | ||
int grad = (1 - y); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s32 instead of int
no brackets
src/mapgen_carpathian.cpp
Outdated
// Gradient | ||
int grad = (1 - y); | ||
// Shallow seabed | ||
if (y < water_level) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since action is a single line no need for curly brackets
src/mapgen_carpathian.h
Outdated
|
||
private: | ||
s16 large_cave_depth; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add s32 grad_wl;
src/mapgen_carpathian.cpp
Outdated
int grad = (1 - y); | ||
// Shallow seabed | ||
if (y < water_level) { | ||
grad = grad_wl + (water_level - y) * 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use a ternary operator to reduce all this to a single line:
s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
src/mapgen_carpathian.cpp
Outdated
int grad = (1 - y); | ||
// Shallow seabed | ||
if (y < water_level) { | ||
grad = grad_wl + (water_level - y) * 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use a ternary operator to reduce all this to a single line:
s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
Ok, added @paramat recommendations and it looks good to me. |
src/mapgen_carpathian.cpp
Outdated
@@ -60,6 +60,7 @@ MapgenCarpathian::MapgenCarpathian( | |||
cavern_limit = params->cavern_limit; | |||
cavern_taper = params->cavern_taper; | |||
cavern_threshold = params->cavern_threshold; | |||
s32 grad_wl = 1 - water_level; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for s32 as the variable has been initialised as s32 in the .h file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks. Now I understand about the unused variable warning. Fixed.
Ok we can add the lava depth parameter after merge. |
Ok time to test again, looks close to a merge. |
Confirmed that, because of how 'grad' works here, the mapgen terrain itself is locked in position and can't be shifted vertically by altering the 'base' noise. This is not a problem. |
Squash on merge. |
1641bab
to
bb714b1
Compare
This reverts commit ec0cfc5.
Conflicts: builtin/settingtypes.txt minetest.conf.example src/mapgen_carpathian.cpp src/mapgen_carpathian.h
A new mapgen with mountain ranges and sometimes large flattish areas.
EDIT by paramat:
See forum post for some screenshots.