diff --git a/package-lock.json b/package-lock.json index 4419a845..39fbbe1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1243,14 +1243,20 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001283", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", - "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", + "version": "1.0.30001342", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001342.tgz", + "integrity": "sha512-bn6sOCu7L7jcbBbyNhLg0qzXdJ/PMbybZTH/BA6Roet9wxYRm6Tr9D0s0uhLkOZ6MSG+QU6txUgdpr3MXIVqjA==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/caseless": { "version": "0.12.0", @@ -6036,9 +6042,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001283", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", - "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", + "version": "1.0.30001342", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001342.tgz", + "integrity": "sha512-bn6sOCu7L7jcbBbyNhLg0qzXdJ/PMbybZTH/BA6Roet9wxYRm6Tr9D0s0uhLkOZ6MSG+QU6txUgdpr3MXIVqjA==", "dev": true }, "caseless": { diff --git a/src/guides/density-functions.md b/src/guides/density-functions.md index 7554ac34..46b6fb85 100644 --- a/src/guides/density-functions.md +++ b/src/guides/density-functions.md @@ -1,78 +1,28 @@ --- -title: How the noise router and density functions work +title: Density function types and their configuration versions: - '1.18.2' - '1.19' tags: - worldgen - noise + - density --- -[Density functions](/worldgen/density-function/) are used by the dimension generator to generate the terrain. They make up mathematical expressions that decide whether or not a block should be solid terrain. - -## Noise router -The noise router is a piece of configuration in [noise settings](/worldgen/noise-settings/). It's a collection of density functions, some used for the biome layout, aquifers, or ore veins. The one that decides the terrain is **f`final_density`**. This density function will be computed for every block position. If it returns a value greater than n`0` the default block will be placed, otherwise either air or the default fluid will be placed. - -With this information we can make the most basic noise router, one where every density function is set to n`0`. As predicted, this will result in a void world. Similarly, setting `"final_density": 1` will result in a world completely filled with stone. - -**`data/minecraft/worldgen/noise_settings/overworld.json`** -```json -{ - "sea_level": 0, - "disable_mob_generation": false, - "aquifers_enabled": false, - "ore_veins_enabled": false, - "legacy_random_source": false, - "default_block": { - "Name": "minecraft:stone" - }, - "default_fluid": { - "Name": "minecraft:water", - "Properties": { - "level": "0" - } - }, - "noise": { - "min_y": 0, - "height": 256, - "size_horizontal": 2, - "size_vertical": 2 - }, - "noise_router": { - "barrier": 0, - "fluid_level_floodedness": 0, - "fluid_level_spread": 0, - "lava": 0, - "temperature": 0, - "vegetation": 0, - "continents": 0, - "erosion": 0, - "depth": 0, - "ridges": 0, - "initial_density_without_jaggedness": 0, - "final_density": 0, - "vein_toggle": 0, - "vein_ridged": 0, - "vein_gap": 0 - }, - "spawn_target": [], - "surface_rule": { - "type": "minecraft:sequence", - "sequence": [] - } -} -``` +[Density functions](/worldgen/density-function/) are used by the dimension generator to generate the terrain. They make up mathematical expressions that decide whether or not a block should be solid terrain. ## Density functions -In the above example all the density functions are constant numbers, but they don't have to be. Another option is to reference a density function file. Vanilla has some builtin density functions, for example: - +There are 3 ways to specify a density function. The first is simply as a constant number. The density function will always return that value ```json -"final_density": "minecraft:overworld/base_3d_noise" +0.58 ``` -You can create your own density functions in the `worldgen/density_function` folder. +Another option is to reference a density function file. Vanilla has some builtin density functions, but you can create your own density functions in the `worldgen/density_function` folder. +```json +"minecraft:overworld/base_3d_noise" +``` -All the other density function types are defined as an object with a `"type"` field and optionally more fields. For example: +All the other density function types are defined as an object with a f`type` field and optionally more fields. ```json { "type": "minecraft:noise", @@ -81,8 +31,8 @@ All the other density function types are defined as an object with a `"type"` fi "y_scale": 0.5 } ``` -
-The following is a list of all density functions in {#version#} + +## Types ### `abs` Calculates the absolute value of another density function. @@ -94,7 +44,7 @@ Adds two density functions together. * f`argument2`: The second density function ### `beardifier` -Adds beards for structures (see the `terrain_adaptation` field). +Adds beards for structures ({#[1.18.2] see the f`adapt_noise` field in [structures](/worldgen/structure-feature/) #}{#[1.19] see the f`terrain_adaptation` field in [structures](/worldgen/structure/) #}). *This density function has no extra fields* @@ -166,7 +116,7 @@ Multiplies two density functions. * f`argument2`: The second density function ### `noise` -The noise density function samples a noise. +The noise density function samples a [noise](/worldgen/noise/). * f`noise`: A reference to a `worldgen/noise` file * f`xz_scale`: Scales the X and Z inputs before sampling * f`y_scale`: Scales the Y input before sampling @@ -184,7 +134,7 @@ If the input is negative, returns a quarter of the input. Otherwise returns the * f`argument`: The input density function ### `range_choice` -Computes the input value, and depending on that result returns one of two other density functions. +Computes the input value, and depending on that result returns one of two other density functions. Basically an if-then-else statement. * f`input`: The input density function * f`min_inclusive`: The lower bound of the range * f`max_exclusive`: The upper bound of the range @@ -192,16 +142,16 @@ Computes the input value, and depending on that result returns one of two other * f`when_out_of_range`: Density function that will be returned When the input is outside the range ### `shift` -Computes the input density at `(x/4, y/4, z/4)`. -* f`argument`: The input density function +Samples a noise at `(x/4, y/4, z/4)`. +* f`argument`: A reference to a `worldgen/noise` file ### `shift_a` -Computes the input density at `(x/4, 0, z/4)`. -* f`argument`: The input density function +Samples a noise at `(x/4, 0, z/4)`. +* f`argument`: A reference to a `worldgen/noise` file ### `shift_b` -Computes the input density at `(z/4, x/4, 0)`. -* f`argument`: The input density function +Samples a noise at `(z/4, x/4, 0)`. +* f`argument`: A reference to a `worldgen/noise` file ### `shifted_noise` Similar to [`noise`](#noise), but first shifts the input coordinates. diff --git a/src/guides/noise-router.md b/src/guides/noise-router.md new file mode 100644 index 00000000..a647e666 --- /dev/null +++ b/src/guides/noise-router.md @@ -0,0 +1,121 @@ +--- +title: How terrain is generated using the noise router +versions: + - '1.18.2' + - '1.19' +tags: + - worldgen + - noise + - density +--- + +The noise router is a piece of configuration in [noise settings](/worldgen/noise-settings/). It's a collection of [density functions](/guides/density-functions/), some used for the biome layout, aquifers, or ore veins. + +## Final density +The density function that decides the terrain is f`final_density`. This density function will be computed for every block position. If it returns a value greater than n`0` the default block will be placed, otherwise either air or the default fluid will be placed. + +With this information we can make the most basic noise router, one where every density function is set to n`0`. As predicted, this will result in a void world. Similarly, setting j`"final_density": 1` will result in a world completely filled with stone. + +**`data/minecraft/worldgen/noise_settings/overworld.json`** +```json +{ + "sea_level": 63, + "disable_mob_generation": false, + "aquifers_enabled": false, + "ore_veins_enabled": false, + "legacy_random_source": false, + "default_block": { + "Name": "minecraft:stone" + }, + "default_fluid": { + "Name": "minecraft:water", + "Properties": { + "level": "0" + } + }, + "noise": { + "min_y": -64, + "height": 384, + "size_horizontal": 2, + "size_vertical": 2 + }, + "noise_router": { + "barrier": 0, + "fluid_level_floodedness": 0, + "fluid_level_spread": 0, + "lava": 0, + "temperature": 0, + "vegetation": 0, + "continents": 0, + "erosion": 0, + "depth": 0, + "ridges": 0, + "initial_density_without_jaggedness": 0, + "final_density": 0, + "vein_toggle": 0, + "vein_ridged": 0, + "vein_gap": 0 + }, + "spawn_target": [], + "surface_rule": { + "type": "minecraft:sequence", + "sequence": [] + } +} +``` + +## Flat world +Let's continue with a simple density function that creates a flat world at Y=n`128`. Instead of n`0`, we now have this as the f`final_density`: +```json +{ + "type": "minecraft:y_clamped_gradient", + "from_y": -64, + "to_y": 320, + "from_value": 1, + "to_value": -1 +} +``` +The image below illustrates how s`y_clamped_gradient` works. In this example positions at Y=n`-64` will get a density of n`1` and positions at Y=n`320` will get a density of n`-1`. + +![illustration of Y coordinates getting mapped the [-1, 1] range](https://user-images.githubusercontent.com/17352009/170406782-f7331402-0149-47e1-871e-6aff0c1ab1be.png) + +And the result looks like this: + +![a flat world](https://user-images.githubusercontent.com/17352009/170412400-52b1db55-3daf-48a9-b436-22119fe9ba06.png) + + +## First noise +To bring some variety to the world we need noise. We can improve the existing density function by adding a noise to it, like this: +```json +{ + "type": "minecraft:add", + "argument1": { + "type": "minecraft:y_clamped_gradient", + "from_y": -64, + "to_y": 320, + "from_value": 1, + "to_value": -1 + }, + "argument2": { + "type": "minecraft:noise", + "noise": "minecraft:gravel", + "xz_scale": 2, + "y_scale": 0 + } +} +``` + +We get the following result. The height of the terrain is based on a noise that varies along the X and Z coordinates. + +![terrain with random elevations](https://user-images.githubusercontent.com/17352009/170411319-2a797950-95c4-4b90-b1a5-ff2ae4ae66ef.png) + +To make the terrain smoother, we can stretch the noise by altering the f`xz_scale` field. This is the result with j`"xz_scale": 0.5`: + +![terrain with smooth hills](https://user-images.githubusercontent.com/17352009/170411382-6a84f017-5c71-4e63-b90d-c17104ef57b1.png) + +To get overhangs, the noise also needs to vary along the Y coordinate. The following is with j`"xz_scale": 1` and j`"y_scale": 1`. + +![](https://user-images.githubusercontent.com/17352009/170412018-757999be-4595-4be8-9943-a3d3395a2add.png) + +## Splines +🚧 *to be continued* 🚧 diff --git a/src/styles/global.css b/src/styles/global.css index c22579f7..eb322bc7 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1679,7 +1679,8 @@ hr { .guide-content pre > code { display: block; padding: 0.8em; - margin: 0.2em 0 0.5em; + margin-top: 4px; + margin-bottom: 20px; overflow-x: auto; }