linkWorld generation
This guide shows how to build custom world generation using Kore’s Kotlin DSL. It maps the common datapack JSON files described on the Minecraft Wiki to concise Kotlin builders, and links to authoritative references for each concept.
- What worldgen is: terrain, biomes, carvers, features, and structures placed procedurally per chunk. See World generation.
- Cross‑references: see Predicates for condition logic in other features, and Test Features to automate validation with GameTest.
Biomes define climate, visuals, mob spawns, carvers, and the placed features list for each decoration step.
linkCarvers (caves/canyons)
Configured carvers remove terrain to form cave systems and canyons.
linkDecoration Steps
Minecraft runs 11 decoration steps in order for each chunk; structures of a step place before features in that step.
raw_generation
— small end islands
lakes
— lava lakes
local_modifications
— geodes, icebergs
underground_structures
— trial chambers, mineshafts, etc.
surface_structures
— other structures, desert wells, blue ice patches
strongholds
— unused (strongholds use surface_structures)
underground_ores
— ore blobs, sand/gravel/clay disks
underground_decoration
— infested blobs, nether gravel/blackstone, nether ores
fluid_springs
— water/lava springs
vegetal_decoration
— trees, cacti, kelp, vegetation
top_layer_modification
— freeze top layer
Reference: Decoration steps
linkDensity Functions and Noises
Low‑level noise graph pieces used by the noise router and terrain shaping.
linkDimension
Represents one world. Binds a dimension_type
to a generator (noise/flat/debug) and optional biome source.
linkDimension Type
Controls fundamental world rules (skylight, ceilings, respawn rules, height, infiniburn, etc.).
- Configured feature: what to place (tree, ore, etc.) with parameters.
- Placed feature: where/how often to place (count, height, rarity, biome filters).
References: Configured feature, Placed feature
linkFlat Level Generator Presets
Expose superflat presets in the world creation UI.
linkNoise Settings (terrain)
Defines vertical range, aquifers/veins toggles, default blocks/fluids, noise router graph, spawn targets, and surface rules.
linkOutput Paths (generated by Kore)
Kore APIs generate JSON under standard datapack directories (replace <ns>
with your namespace):
DataPack.biome("...")
→ data/<ns>/worldgen/biome/<fileName>.json
DataPack.configuredCarver("...")
→ data/<ns>/worldgen/configured_carver/<fileName>.json
DataPack.configuredFeature("...")
→ data/<ns>/worldgen/configured_feature/<fileName>.json
DataPack.densityFunction("...")
→ data/<ns>/worldgen/density_function/<fileName>.json
DataPack.dimension("...")
→ data/<ns>/dimension/<fileName>.json
DataPack.dimensionType("...")
→ data/<ns>/dimension_type/<fileName>.json
DataPack.flatLevelGeneratorPreset("...")
→ data/<ns>/worldgen/flat_level_generator_preset/<fileName>.json
DataPack.noise("...")
→ data/<ns>/worldgen/noise/<fileName>.json
DataPack.noiseSettings("...")
→ data/<ns>/worldgen/noise_settings/<fileName>.json
DataPack.processorList("...")
→ data/<ns>/worldgen/processor_list/<fileName>.json
DataPack.structureSet("...")
→ data/<ns>/worldgen/structure_set/<fileName>.json
DataPack.structures { ... }
→ data/<ns>/worldgen/structure/<fileName>.json
(via the builder)
DataPack.templatePool("...")
→ data/<ns>/worldgen/template_pool/<fileName>.json
DataPack.worldPreset("...")
→ data/<ns>/worldgen/world_preset/<fileName>.json
- Processor list: per‑piece processing (rules, integrity, gravity, etc.) — Processor list
- Template pool: weighted jigsaw pieces and fallback — Template pool
- Configured structure: structure type config (biomes, step, adaptations) — Structure definition
- Structure set: world‑scale placement and spacing — Structure set
linkWorld Preset (wire everything & expose in UI)
Defines the dimension set for a selectable world creation preset.
linkEnd‑to‑end example: simple custom Overworld‑like dimension
linkTips, validation, and testing
If you are new to datapacks, read the high‑level overview first: World generation. It explains the order of operations (noise → surface → decorations → lighting/spawning) and how the pieces fit together.
linkComplete example: Aether‑like dimension
import io.github.ayfri.kore.DataPack
import io.github.ayfri.kore.generated.Blocks
import io.github.ayfri.kore.generated.DimensionTypes
import io.github.ayfri.kore.generated.EntityTypes
import io.github.ayfri.kore.generated.arguments.worldgen.types.BiomeArgument
import io.github.ayfri.kore.features.worldgen.biome.types.spawnCost
import io.github.ayfri.kore.features.worldgen.biome.types.spawnCosts
import io.github.ayfri.kore.features.worldgen.biome.types.spawner
import io.github.ayfri.kore.features.worldgen.biome.types.spawners
import io.github.ayfri.kore.features.worldgen.configuredcarver.Cave
import io.github.ayfri.kore.features.worldgen.configuredcarver.caveConfig
import io.github.ayfri.kore.features.worldgen.configuredfeature.Target
import io.github.ayfri.kore.features.worldgen.configuredfeature.blockstateprovider.simpleStateProvider
import io.github.ayfri.kore.features.worldgen.configuredfeature.configurations.ore
import io.github.ayfri.kore.features.worldgen.configuredfeature.configurations.simpleBlock
import io.github.ayfri.kore.features.worldgen.configuredfeature.configurations.tree
import io.github.ayfri.kore.features.worldgen.configuredfeature.configurations.tree.foliageplacer.blobFoliagePlacer
import io.github.ayfri.kore.features.worldgen.configuredfeature.configurations.tree.trunkplacer.straightTrunkPlacer
import io.github.ayfri.kore.features.worldgen.dimension.biomesource.checkerboard
import io.github.ayfri.kore.features.worldgen.heightproviders.uniformHeightProvider
import io.github.ayfri.kore.features.worldgen.noisesettings.rules.conditions.absolute
import io.github.ayfri.kore.features.worldgen.placedfeature.modifiers.biome
import io.github.ayfri.kore.features.worldgen.placedfeature.modifiers.count
import io.github.ayfri.kore.features.worldgen.placedfeature.modifiers.heightRange
import io.github.ayfri.kore.features.worldgen.placedfeature.modifiers.inSquare
import io.github.ayfri.kore.features.worldgen.placedfeature.modifiers.rarityFilter
import io.github.ayfri.kore.features.worldgen.floatproviders.constant
import io.github.ayfri.kore.features.worldgen.intproviders.constant
fun DataPack.createAetherDimension() {
val aetherType = dimensionType("aether_type") {
ambientLight = 0.15f
bedWorks = true
hasCeiling = false
hasRaids = true
hasSkylight = true
height = 384
logicalHeight = 384
minY = -64
natural = true
piglinSafe = false
respawnAnchorWorks = false
ultrawarm = false
}
val aetherNoise = noiseSettings("aether_noise") {
defaultBlock(Blocks.STONE) {}
defaultFluid(Blocks.WATER) { this["level"] = "0" }
noiseOptions(minY = -64, height = 384, sizeHorizontal = 1, sizeVertical = 2)
}
val highlandsTreeCfg = tree {
dirtProvider = simpleStateProvider(Blocks.DIRT)
trunkProvider = simpleStateProvider(Blocks.OAK_LOG)
foliageProvider = simpleStateProvider(Blocks.OAK_LEAVES)
straightTrunkPlacer(baseHeight = 6, heightRandA = 3, heightRandB = 1)
blobFoliagePlacer(radius = constant(2), offset = constant(0), height = 3)
}
val highlandsTree = configuredFeature("aether_highlands_tree", highlandsTreeCfg) {}
val highlandsTreePlaced = placedFeature("aether_highlands_tree_placed", highlandsTree) {
inSquare()
count(constant(10))
heightRange(uniformHeightProvider(64, 128))
biome()
}
val flowerCfg = simpleBlock(toPlace = simpleStateProvider(Blocks.DANDELION))
val flowers = configuredFeature("aether_highlands_flower", flowerCfg) {}
val flowersPlaced = placedFeature("aether_highlands_flower_placed", flowers) {
inSquare()
rarityFilter(3)
heightRange(uniformHeightProvider(64, 128))
biome()
}
val oreCfg = ore(
size = 10,
discardChanceOnAirExposure = 0.1,
targets = listOf(Target())
)
val ore = configuredFeature("aether_coal_ore", oreCfg) {}
val orePlaced = placedFeature("aether_coal_ore_placed", ore) {
inSquare()
count(constant(20))
heightRange(uniformHeightProvider(0, 128))
biome()
}
val forestTreeCfg = tree {
dirtProvider = simpleStateProvider(Blocks.DIRT)
trunkProvider = simpleStateProvider(Blocks.SPRUCE_LOG)
foliageProvider = simpleStateProvider(Blocks.SPRUCE_LEAVES)
straightTrunkPlacer(baseHeight = 8, heightRandA = 4, heightRandB = 2)
blobFoliagePlacer(radius = constant(3), offset = constant(0), height = 4)
}
val forestTree = configuredFeature("aether_forest_tree", forestTreeCfg) {}
val forestTreePlaced = placedFeature("aether_forest_tree_placed", forestTree) {
inSquare()
count(constant(16))
heightRange(uniformHeightProvider(64, 140))
biome()
}
val shoreTreePlaced = placedFeature("aether_shore_tree_placed", highlandsTree) {
inSquare()
count(constant(3))
heightRange(uniformHeightProvider(62, 75))
biome()
}
val shoreFlowersPlaced = placedFeature("aether_shore_flowers_placed", flowers) {
inSquare()
count(constant(5))
heightRange(uniformHeightProvider(62, 75))
biome()
}
val caveCfg = caveConfig {
probability = 0.08
y = uniformHeightProvider(32, 128)
yScale = constant(0.5f)
lavaLevel = absolute(8)
horizontalRadiusMultiplier = constant(1.0f)
verticalRadiusMultiplier = constant(0.7f)
floorLevel = constant(-0.2f)
}
val cave = configuredCarver("aether_cave", caveCfg) {}
val highlands = biome("aether_highlands") {
downfall = 0.3f
hasPrecipitation = true
temperature = 0.8f
effects {
fogColor = 0xBFEFFF
skyColor = 0x99D9FF
waterColor = 0x34A7F0
waterFogColor = 0x0A2C4F
}
spawners {
creature {
spawner(EntityTypes.COW, 6, 2, 4)
spawner(EntityTypes.SHEEP, 8, 2, 4)
}
monster {
spawner(EntityTypes.SKELETON, 80, 1, 2)
spawner(EntityTypes.ZOMBIE, 80, 1, 2)
}
}
spawnCosts {
this[EntityTypes.COW] = spawnCost(1.2f, 0.1f)
this[EntityTypes.SHEEP] = spawnCost(1.0f, 0.08f)
}
carvers { air(cave) }
features {
undergroundOres = listOf(orePlaced)
vegetalDecoration = listOf(highlandsTreePlaced, flowersPlaced)
}
}
val forest = biome("aether_forest") {
downfall = 0.5f
hasPrecipitation = true
temperature = 0.7f
effects {
fogColor = 0xB0E3FF
skyColor = 0x8ECCFF
waterColor = 0x3095D8
waterFogColor = 0x0A2644
}
spawners {
creature {
spawner(EntityTypes.COW, 6, 2, 4)
spawner(EntityTypes.SHEEP, 6, 2, 4)
spawner(EntityTypes.WOLF, 4, 1, 2)
}
monster {
spawner(EntityTypes.SKELETON, 100, 1, 2)
spawner(EntityTypes.SPIDER, 60, 1, 2)
spawner(EntityTypes.ZOMBIE, 100, 1, 2)
}
}
carvers { air(cave) }
features {
undergroundOres = listOf(orePlaced)
vegetalDecoration = listOf(forestTreePlaced, flowersPlaced)
}
}
val shores = biome("aether_shores") {
downfall = 0.2f
hasPrecipitation = false
temperature = 0.9f
effects {
fogColor = 0xC6F1FF
skyColor = 0xA2E0FF
waterColor = 0x3AB1FF
waterFogColor = 0x0B2F59
}
spawners {
creature { spawner(EntityTypes.SHEEP, 10, 3, 5) }
monster { spawner(EntityTypes.ZOMBIE, 60, 1, 2) }
}
carvers { air(cave) }
features {
undergroundOres = listOf(orePlaced)
vegetalDecoration = listOf(shoreTreePlaced, shoreFlowersPlaced)
}
}
dimension("aether", type = aetherType) {
noiseGenerator(
settings = aetherNoise,
biomeSource = checkerboard(scale = 3, highlands, forest, shores)
)
}
worldPreset("aether_preset") {
dimension(DimensionTypes.OVERWORLD) { type = aetherType }
}
}
Tips:
- Validate each JSON via the Wiki pages linked above as you fill in real configs.
- Keep feature counts and structure spacing reasonable for performance.
- Use GameTest to validate worldgen deterministically; see Test Features.