Creating Carving From Scratch

This guide will continue the process of creating a new Terra config pack from the beginning with creating caves through carving.

If you haven’t already, please read the Config Development Introduction & Creating A Pack From Scratch for more information before continuing.

If you’re stuck or need an example, you can find reference config packs for this guide on the GitHub repo.

Setting up Carving

PROCEDURE

1. Add cached sampler

Utilizing a cached sampler will make config development easier when creating noise sampler expressions.

Cached samplers allow a sampler to be used anywhere in the pack for noise sampler expressions and the TerraScript Sampler Function.

Cached samplers are extremely convenient especially when you have various expressions that utilize the same noise sampler.

Open your pack manifest in your editor of choice.

Add the following lines below to cache some samplers.

pack.yml
 1id: YOUR_PACK_ID
 2
 3addons:
 4  ...
 5
 6stages:
 7  ...
 8
 9samplers:
10  simplex:
11    dimensions: 2
12    type: FBM
13    octaves: 4
14    sampler:
15      type: OPEN_SIMPLEX_2
16      frequency: 0.0075
17  simplex3:
18    dimensions: 3
19    type: FBM
20    octaves: 4
21    sampler:
22      type: OPEN_SIMPLEX_2
23      frequency: 0.0075

These samplers are little different from your usual ones through the use of fractalization.

The fractalizer type FBM combines multiple layers (or octaves) of the noise sampler in order to add more detail to the sampler.

The newly cached simplex sampler will be generally used for terrain samplers as they typically utilize 2 dimensions.

The newly cached simplex3 sampler will be used for the carving that will implemented in this guide as they work with 3 dimensions.

2. Add carving abstract config

An abstract carving config will be utilized for biomes to easily extend and inherit the carving.

Create a blank config file with the file name carving_land.yml.

Set the config type via the type parameter, config id, and abstract as shown below.

carving_land.yml
1id: CARVING_LAND
2type: BIOME
3abstract: true

Add the following lines to add the carving sampler.

carving_land.yml
 1id: CARVING_LAND
 2type: BIOME
 3abstract: true
 4
 5carving:
 6  sampler:
 7    dimensions: 3
 8    type: EXPRESSION
 9    variables:
10
11      carvingThreshold: 0.55 # Higher = less carving
12      carvingMinHeight: -63
13      carvingMaxHeight: 140
14      carvingCap: 1 # Caps the amount of base carving
15
16      spaghettiStrengthLarge: 0.59
17      spaghettiStrengthSmall: 0.57
18
19    expression: |
20      -carvingThreshold
21      + if(y<carvingMinHeight||y>carvingMaxHeight,0, // Skip unnecessary calculations
22        min(carvingCap,
23          // Spaghetti Caves
24          max(
25            spaghettiStrengthLarge * ((-(|simplex3(x,y+0000,z)|+|simplex3(x,y+1000,z)|)/2)+1),
26            spaghettiStrengthSmall * ((-(|simplex3(x,y+2000,z)|+|simplex3(x,y+3000,z)|)/2)+1)
27          )
28        )
29      )

Tip

It is recommended to have read the Creating Terrain From Scratch and the TerraScript Syntax to have a better understanding.

This carving sampler will carve out non-air blocks between the set maximum y-level of 140 and minimum y-level -63.

The sampler expression will produce results that resemble that of spaghetti caves.

This guide will not go into the full depth of how this carving sampler works, but at least give a brief limited explanation.

Starting with the expression is with the carvingThreshold value set to negative, which gets added to by the rest of the expression.

The rest of the expression states that if y is less than carvingMinHeight or y is greater than carvingMaxHeight, then output 0.

This results in no block placement at that coordinate.

The argument after 0 can be seen as the else statement. It contains min() , which takes the lowest value between carvingCap and the max() that takes the highest value between two sets of simplex3 samplers with each sampler slightly offset from the other and added together.

Note

This carving contains only the spaghetti cave aspect from the default overworld config carving, which can be viewed through GitHub.

3. Extend carving abstract

The land biome configs will need to extend CARVING_LAND in order for them to inherit the carving.

Open FIRST_BIOME and SECOND_BIOME in your editor of choice.

Add the CARVING_LAND to the extends parameter list of FIRST_BIOME and SECOND_BIOME.

first_biome.yml
1id: FIRST_BIOME
2type: BIOME
3extends:
4  - BASE
5  - CARVING_LAND
6
7...
second_biome.yml
1id: SECOND_BIOME
2type: BIOME
3extends:
4  - BASE
5  - CARVING_LAND
6
7...

Warning

It is not recommended to add CARVING_LAND to OCEAN_BIOME as the carving is set with a max range value that will result in carved pockets of air with floating water in the ocean.

Another abstract carving config with a reduced max carving height is recommended to avoid this issue.

../../../_images/carving.png

4. Load up your pack

At this stage, your pack should now be capable of caves through carving. You can load up your pack by starting your development client / server which contains the pack you have just defined. You can confirm that your pack has loaded if the pack id (as specified in the pack manifest) appears when using the /packs command, or in your console when starting the server / client up.

If for whatever reason your pack does not load, an error message will show up in console explaining why the pack has failed to load, please read through any of these errors and try to interpret what you may have done wrong, and follow through the previous steps again carefully.

If you still are unable to load the pack, feel free to contact us with any relevant errors.

Attention

If you have loaded the pack and did Creating an Ocean from Scratch previously, you’ll see cases of floating water, which had their adjacent solid blocks carved out by CARVING_LAND.

This issue will be addressed in the next step.

../../../_images/carving-issue.png

5. Floating Water Issue

There are several methods of dealing with the issue of floating water caused by carving.

The simpler method that will be used in this guide is a feature that will place stone blocks in order to contain floating water blocks.

Create a blank config file with the file name contain_floating_water.yml.

Set the config type via the type parameter, and config id as shown below.

contain_floating_water.yml
1id: CONTAIN_FLOATING_WATER
2type: FEATURE

Add the highlighted lines to create this specific feature.

contain_floating_water.yml
 1id: CONTAIN_FLOATING_WATER
 2type: FEATURE
 3
 4distributor:
 5  type: "YES"
 6
 7locator:
 8  type: AND
 9  locators:
10    - type: PATTERN
11      range: &range
12        min: 0
13        max: 63
14      pattern:
15        type: MATCH_AIR
16        offset: 0
17    - type: OR
18      locators:
19        - type: PATTERN
20          range: *range
21          pattern:
22            type: MATCH
23            block: minecraft:water
24            offset: 1
25        - type: ADJACENT_PATTERN
26          range: *range
27          pattern:
28            type: MATCH
29            block: minecraft:water
30            offset: 0
31
32structures:
33  distribution:
34    type: CONSTANT
35  structures: BLOCK:minecraft:stone

The CONTAIN_FLOATING_WATER feature simply looks for air blocks with adjacent patterns of water blocks and places a stone block at that location.

Open your pack manifest in your editor of choice.

Add a generation stage to your pack manifest to allow this feature to generate separately from other features.

The generation stage will be called preprocessors for this guide.

pack.yml
 1id: YOUR_PACK_ID
 2
 3...
 4
 5stages:
 6  - id: preprocessors
 7    type: FEATURE
 8
 9  - id: trees
10    type: FEATURE
11
12  - id: flora
13    type: FEATURE

The CONTAIN_FLOATING_WATER feature could be added individually to every biome config, but that can be tedious depending on the number of biomes your config pack has.

Like in Creating an Ocean from Scratch with an ocean palette, an abstract config can be used to extend features for biomes to inherit and generate.

Open your BASE config in your editor of choice.

Add the following lines for biomes that extend BASE to inherit the preprocessors feature generation from BASE.

base.yml
 1id: BASE
 2type: BIOME
 3abstract: true
 4
 5ocean:
 6  palette: BLOCK:minecraft:water
 7  level: 62
 8
 9features:
10  preprocessors:
11    - CONTAIN_FLOATING_WATER

It’s not a perfect method, but it resolves the issue in a simple manner without much complication.

Conclusion

Now that you’ve verified your pack has loaded correctly and resolved the floating water issue, you can now generate a world with caves!

Reference configurations for this guide can be found on GitHub here.

../../../_images/carving-fixed.png