Starting with Data Packs
Generate Minecraft worlds by map images!
To get started with a custom data pack that uses CTGen, you need to have a basic understanding on how a data pack is structured. For reference, reach out to the Minecraft Wiki. Your data pack structure should look like this:
<data pack name>
├── data
│ ├── <namespace>
│ │ └── worldgen
│ │ ├── map_based -- everything connected to CTGen belongs into this directory
│ │ │ ├── maps -- here are your custom maps saved
│ │ │ │ └── <custom_map>.png
│ │ │ └── zones -- this is where you save custom zones, should be preprocessed
│ │ │ ├── zone_a.json
│ │ │ ├── zone_b.json
│ │ │ ├── zone_c.json
│ │ └── world_preset
│ │ └── <custom_preset>.json -- this world preset should configure the CTGen chunk generator
│ └── minecraft
│ └── tags
│ └── worldgen
│ └── world_preset
│ └── normal.json -- make the world preset available in the selection menu
└── pack.mcmeta
Note that the <custom_preset>.json
and the tag specification are only required so the ChunkGenerator can be read as a custom world preset. Of course, you can also use it in other use cases, such as custom dimensions, but I’ll only explain custom world presets here, since the process is nearly the same.
Zones
Zones are intended to tell CTGen, what specifications and biomes are mapped to what color on the map image. Here’s the general file structure for a Zone:
{
"biome": "minecraft:deep_ocean",
"color": "#002355", // color in hex decimal/html layout
"height": 10, // additional height, added to the surface level. Will be modified by transition
"terrain_modifier": 6.0, // how strongly the noise can swing -> 6 means, hills are up to 6 blocks high, thales can be up to 6 blocks deep. Will be modified by transition
"layers": { // map a block layer to a block placer. See extra sites for more info
"deepslate": "minecraft:deepslate", // always set block "minecraft:deepslate" for layer "deepslate"
"stone": "minecraft:stone",
"dirt": "minecraft:dirt",
"surface": {
type: "ctgen:basic_placer", // some block placer you want to use
value: "minecraft:grass_block" // block player specific args
},
},
"pixel_weight": 1 , // only used for upscaling. A higher weight causes the zone to more aggressively spread
"carver_modifier": 6 // zone specific value for the default carver modifier. Will be modified by transition
}
Generator
The settings define the most important things for the chunk generator and values that are persistent throughout the zones. Since many parameters might be complicated at first, it’s recommended to start using the ones below.
Here’s the world preset used for the Elarth data pack:
{
"dimensions": {
"minecraft:overworld": {
"type": "minecraft:overworld",
"generator": {
"type": "ctgen:map_based_chunk_generator",
"settings": {
"biome_map": "elarth:elarth",
"default_map_biome": "ctgen:deep_ocean",
"zones": [
"ctgen:stony_flats",
"ctgen:snowy_flats",
"ctgen:snowy_slopes",
"ctgen:snowy_mountains",
"ctgen:frozen_lake",
"ctgen:frozen_river",
"ctgen:plains",
"ctgen:forest",
"ctgen:hills",
"ctgen:mountains",
"ctgen:lake",
"ctgen:desert",
"ctgen:badlands",
"ctgen:badlands_mountains",
"ctgen:river",
"ctgen:ocean",
"ctgen:deep_ocean"
]
}
}
}
}
}
For now, you can continue with Zones.
Every parameter not present will be automatically filled with the value of the chunk generator settings below.
Here’s every possible setting mapped to its default value explained, used in a world preset:
{
"dimensions": {
"minecraft:overworld": {
"type": "minecraft:overworld",
"generator": {
"type": "ctgen:map_based_chunk_generator", // important, tells Minecraft to use the CTGen Chunk Generator
"settings": { // this is where the actual ChunkGenerator settings start
"biome_map": "<namespace>:<custom_map>", // the id of your map image
"pixels_are_chunks": false, // if true, the map image will be upscaled. Use with caution! you might rather upscale the image before putting it into the data pack! A pixel of a map that can be read by the ChunkGenerator must equal 4 blocks.
"zones": [ // list all zones that should be used for generation. Don't add more than one zone with the same color!
"<namespace>:zone_a",
"<namespace>:zone_b",
"<namespace>:zone_c"
],
"default_map_biome": "<namespace>:zone_a", // a default biome. Will be used for chunks outside the map image
"layers": [ // define the block layers. The order is important- if a block can be part of multiple layers, the first layer is used!
{
"type": "ctgen:surface_layer", // a block layer that only applies on the surface block
"name": "surface", // the name of the layer so Zones can modify it
"fallback": { // a fallback block player in case the current zone doesn't have a custom one
"type": "ctgen:basic_placer",
"value": "minecraft:grass_block"
}
},
{
"type": "ctgen:height_layer", // a block layer that depends on the absolute y
"min": -65, // min y where the layer is applied
"max": 0, // max y where the layer is applied
"limit_to_surface": true, // whether the layer should stop on the surface level, if the surface is below "max"
"shift": true, // whether the layer transition should be "shifted" for each block. adds a bit more beautiful noise to it
"name": "deepslate",
"has_caves": true, // whether carvers should be applied within this layer
"fallback": "minecraft:deepslate"
},
{
"type": "ctgen:sea_layer", // fills every block between the surface and the sea level, if the surface is below the sea level
"name": "sea",
"fallback": "minecraft:water"
},
{
"type": "ctgen:weight_layer", // a block layer that depends on the relative y - y in percent between minY and surface height
"min_percentage": 0, // value between 0 and 1
"max_percentage": 0.96, // value between 0 and 1
"shift": true,
"name": "stone",
"has_caves": true,
"fallback": "minecraft:stone"
},
{
"type": "ctgen:weight_layer",
"min_percentage": 0.96,
"max_percentage": 2, // very high value since the surface will be applied first and the weight layer only runs up to the surface. By using 2, there won't be a gap between dirt and surface, not even with "shift" enabled
"shift": true,
"name": "dirt",
"has_caves": true,
"fallback": "minecraft:dirt"
}
],
"surface_level": 66, // the default surface level if there won't be noise nor zone-specific height
"min_y": -32, // lowest possible y where blocks can still be placed
"gen_height": 256, // highest y value to where the ChunkGenerator should place blocks
"sea_level": 64, // the sea level- if the surface is below this point, it'll be filled with water
"terrain": { // set a logic to get the surface height
"type": "ctgen:basic_surface", // the default surface height supplier
"noise": { // optional. the noise codec
"octaves": [ // noise octaves that should be applied in the correct order
{
"frequency": 1,
"amplitude": 1
},
{
"frequency": 2,
"amplitude": 0.5
},
{
"frequency": 4,
"amplitude": 0.25
}
],
"persistence": 0.5, // multiplies the amplitude for each octave
"stretch": 250 // stretch the noise
}
},
"transition": 31, // how large the transition should be. Modify with caution! A high value might result that it seems like the ChunkGenerator skips thin zones as rivers!
"spawn_pixel_x": 0, // pixel on the map image that should be parsed as 0 | 0 in game. note that this is the pixel position on the upscaled image, if "pixels_are_chunks" == true
"spawn_pixel_y": 0, // see above
"carver": { // algorithm that 'carves' blocks out, resulting in caves
"type": "ctgen:noise_carver",
"noise": { // optional. the noise codec
"octaves": [
{
"frequency": 1,
"amplitude": 1
},
{
"frequency": 0.5,
"amplitude": 2
}
],
"persistence": 2, // multiplies the amplitude for each octave
"stretch": 63, // stretch the noise
"stretch_y": 47 // stretch the noise
},
"threshold": 0.55
},
"default_carver_modifier": 6 // divide through 16 and add to the cave threshold, that's the threshold on the surface
}
}
}
}
}
Continue with Zones