diff --git a/doc/lua_api.md b/doc/lua_api.md index 7ce6a543e6..845959d134 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -6704,7 +6704,7 @@ Environment access in that order. * `mapgen_limit` is an optional number. If it is absent, its value is that of the *active* mapgen setting `"mapgen_limit"`. - * `chunksize` is an optional number. If it is absent, its value is that + * `chunksize` is an optional number or vector. If it is absent, its value is that of the *active* mapgen setting `"chunksize"`. * `core.get_mapgen_chunksize()` * Returns the currently active chunksize of the mapgen, as a vector. diff --git a/doc/world_format.md b/doc/world_format.md index 909613d0b4..2dda2994e9 100644 --- a/doc/world_format.md +++ b/doc/world_format.md @@ -249,7 +249,7 @@ Example content: # Map File Format -Luanti maps consist of `MapBlock`s, chunks of 16x16x16 nodes. +Luanti maps consist of `MapBlock`s, each holds 16x16x16 nodes. In addition to the bulk node data, `MapBlock`s stored on disk also contain other things. diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index c31d12ac7e..625aeab550 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -1073,9 +1073,27 @@ void MapgenParams::readParams(const Settings *settings) settings->getS16NoEx("mapgen_limit", mapgen_limit); settings->getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); - s16 tmp; - settings->getS16NoEx("chunksize", tmp); - chunksize = v3s16(rangelim(tmp, 1, 24)); + std::string chunksize_str; + settings->getNoEx("chunksize", chunksize_str); + if (is_number(chunksize_str)) { + chunksize = v3s16(stoi(chunksize_str, 1, 999)); + } else if (auto tmp = str_to_v3f(chunksize_str); tmp.has_value()) { + chunksize = v3s16( + rangelim(tmp->X, 1, 999), + rangelim(tmp->Y, 1, 999), + rangelim(tmp->Z, 1, 999) + ); + } else if (!chunksize_str.empty()) { + errorstream << "MapgenParams: invalid chunksize \"" << chunksize_str + << "\"" << std::endl; + } + // Finally check the volume limit + if (u32 v = chunksize.X * chunksize.Y * chunksize.Z; v > MAX_CHUNK_VOLUME) { + errorstream << "MapgenParams: chunksize " << chunksize + << " is too big (volume > " << MAX_CHUNK_VOLUME + << "), falling back to the default." << std::endl; + chunksize = v3s16(5); + } delete bparams; bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL); @@ -1092,9 +1110,15 @@ void MapgenParams::writeParams(Settings *settings) const settings->setU64("seed", seed); settings->setS16("water_level", water_level); settings->setS16("mapgen_limit", mapgen_limit); - settings->setS16("chunksize", chunksize.X); // TODO settings->setFlagStr("mg_flags", flags, flagdesc_mapgen); + // Write as number if cubic, for backwards-compatibility + if (chunksize.X == chunksize.Y && chunksize.Y == chunksize.Z) { + settings->setS16("chunksize", chunksize.X); + } else { + settings->setV3F("chunksize", v3f::from(chunksize)); + } + if (bparams) bparams->writeParams(settings); } diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index fd645d9a59..a5afb2a6d3 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -127,6 +127,9 @@ struct MapgenParams { virtual void setDefaultSettings(Settings *settings) {}; s32 getSpawnRangeMax(); + + // Mostly arbitrary limit + constexpr static u32 MAX_CHUNK_VOLUME = 2000; }; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 126b7afc78..06b07399b1 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -861,6 +861,8 @@ int ModApiMapgen::l_get_mapgen_edges(lua_State *L) v3s16 chunksize; if (lua_isnumber(L, 2)) { chunksize = v3s16(lua_tointeger(L, 2)); + } else if (lua_istable(L, 2)) { + chunksize = check_v3s16(L, 2); } else { chunksize = params->chunksize; }