API

Генерация мира

Руды, деревья, цветы, структуры и биомы, которые появляются в мире сами. Ты объявляешь, что и где, а новые чанки это получают.

Руды

content/ruby_ore.craftCraftScript
block "ruby_ore" { hardness: 3, tool: "pickaxe", tier: "iron" }

ore "ruby_ore" {
    replaces: "stone_and_deepslate"
    size: 9
    per_chunk: 8
    height: [-60, 60]
}
Свойство Значения По умолчанию
block блок, который нужно поставить: "mymod:other" блок с тем же именем, что и руда
replaces stone, deepslate, stone_and_deepslate (верхний мир), netherrack (Нижний мир) или end_stone (Край) stone_and_deepslate
size блоков в жиле, 1–64 8
per_chunk жил, которые пробуются на чанк 8
height [min, max], диапазон высот [-64, 64]
biomes только в этих биомах: id или теги каждый биом, где есть её порода

Без biomes руда появляется во всех биомах измерения, к которому относится replaces; руда с end_stone — во всех биомах Края. Сам блок объявляется как любой другой, со своей прочностью, инструментом и добычей; смотри Блоки, предметы и рецепты.

content/void_ore.craftCraftScript
ore "void_ore" {
    replaces: "end_stone"
    size: 5
    per_chunk: 6
    height: [10, 80]
    biomes: ["mymod:crystal_glade"]
}

Деревья

Дерево — это прямой ствол с шаром из листвы. Объяви два блока, затем дерево.

content/ruby_tree.craftCraftScript
block "ruby_log" { hardness: 2, tool: "axe", sound: "wood" }
block "ruby_leaves" { hardness: 0.2, transparent: true, sound: "grass" }

tree "ruby_tree" {
    trunk: "ruby_log"
    leaves: "ruby_leaves"
    height: 6
    height_variation: 2
    leaves_radius: 2
    per_chunk: 2
    biomes: ["#minecraft:is_forest", "minecraft:plains"]
}
Свойство Значения По умолчанию
trunk блок ствола, из мода или из игры: "ruby_log", "minecraft:oak_log" —
leaves блок листвы —
height высота ствола в блоках 5
height_variation насколько высота отличается от дерева к дереву 2
leaves_radius радиус шара листвы в блоках 2
per_chunk деревьев, которые пробуют создать на чанк 1
biomes биомы, где это появляется: id или теги —

Биомы указываются по id (minecraft:plains) или по тегу (#minecraft:is_forest), можно смешивать. Ствол и листва могут быть блоками мода или игры.

Растения и заросли

Растение — это блок, нарисованный как два скрещённых изображения, как цветок: ничто с ним не сталкивается, а свет проходит насквозь. Его текстура — textures/block/ruby_flower.png, с прозрачным фоном.

content/ruby_flowers.craftCraftScript
block "ruby_flower" { plant: true, hardness: 0 }

patch "ruby_flowers" {
    block: "ruby_flower"
    biomes: ["#minecraft:is_overworld"]
    rarity: 4
    size: 32
    spread: 7
}

Заросли рассеивают растения по миру:

Свойство Значения По умолчанию
block блок растения —
biomes биомы, где это появляется: id или теги —
rarity одни заросли на столько чанков 4
size растений, которые пытается поставить каждая заросль 32
spread наибольшее расстояние от центра зарослей в блоках 7

Растения ставятся только в воздухе, на поверхности земли обычного мира (трава, земля, мох и грязь). Для растений на другой земле, на стенах или свисающих с потолков напиши фичу: см. Генерация кодом.

Структуры

Структура — это постройка, которую ты делаешь сам:

  1. Построй её в игре.
  2. Сохрани её блоком структуры.
  3. Скопируй файл .nbt в папку structures/ мода: рядом со скриптами в моде CraftScript или в assets/<id мода>/structures/ в jar-файле на Kotlin или Java.

Затем объяви её:

content/ruby_shrine.craftCraftScript
structure "ruby_shrine" {
    file: "ruby_shrine"
    biomes: ["#minecraft:is_overworld"]
    spacing: 24
    separation: 8
    buried: false
}
Свойство Значения По умолчанию
file имя файла .nbt без расширения первый вариант или имя структуры
biomes биомы, где это появляется: id или теги —
spacing примерно одна структура на столько чанков 24
separation никогда ближе, чем столько чанков; меньше spacing 8
buried true погружает её в землю, для руин false
offset_y на сколько блоков выше поверхности, на которой она стоит; отрицательное значение погружает её 0
adapt_ground true засыпает землю под ней и расчищает вокруг; false ставит её как есть true
heights [min, max]: на случайной высоте из этого диапазона, где бы ни была поверхность, а не на поверхности (дом в небе) на поверхности

Найти её можно командой /locate structure <id мода>:ruby_shrine, поставить — командой /place structure <id мода>:ruby_shrine.

Варианты, замены и разрушение

Одна структура может состоять из нескольких файлов, а её блоки могут меняться при установке. Так получаются руины, которые никогда не бывают в точности одинаковыми:

content/old_ruins.craftCraftScript
structure "old_ruins" {
    variants: [{ file: "ruins_small", weight: 3 }, "ruins_tower"]
    biomes: ["#minecraft:is_forest"]
    spacing: 20
    separation: 6
    offset_y: -2
    skip: ["minecraft:air"]
    replace: [{ block: "minecraft:stone_bricks", with: "minecraft:cracked_stone_bricks", chance: 0.3 }]
    decay: { left: 0.8, blocks: ["minecraft:stone_bricks", "minecraft:cracked_stone_bricks"] }
}
Свойство Значения По умолчанию
variants файлы, один из которых она представляет: имена или { file, weight }; один выбирается случайно, с учётом веса только file, вес 1
skip блоки её файлов, которые не ставятся. "minecraft:air" сохраняет блоки мира там, где в файле воздух —
replace [{ block, with, chance }]: блок её файлов становится другим с этой вероятностью (больше 0 и до 1) вероятность 1
decay { left, blocks }: сохраняется только left (0–1) от blocks (id или теги); без blocks — от любых блоков сохраняется всё

Структуры из соединяющихся частей

Деревня или подземелье состоит из частей, которые соединяются: улица ведёт к дому, коридор — к комнате. Каждая часть — это файл с игровыми блоками соединения (jigsaw), и каждый такой блок называет пул, из которого берётся следующая часть, в виде <id мода>:<пул>. Объяви пулы; структура начинается с первого.

content/hamlet.craftCraftScript
structure "hamlet" {
    biomes: ["minecraft:plains"]
    spacing: 34
    separation: 8
    depth: 6
    pools: [
        { name: "hamlet/square", pieces: [{ file: "hamlet/square" }] },
        { name: "hamlet/streets", fallback: "hamlet/street_ends",
          pieces: [{ file: "hamlet/street_straight", weight: 3, follows_ground: true },
                   { file: "hamlet/street_corner", follows_ground: true }],
          replace: [{ block: "minecraft:stone_bricks", with: "minecraft:oak_planks", where: "minecraft:water" }] },
        { name: "hamlet/street_ends", pieces: [{ file: "hamlet/street_end", follows_ground: true }] },
        { name: "hamlet/houses", none: 2,
          pieces: [{ file: "hamlet/house_small", weight: 4 }, { file: "hamlet/house_big" }] },
    ]
}
Свойство Значения По умолчанию
pools пулы частей; первый из них — то, с чего она начинается одна часть, из variants или file
depth на сколько частей от первой она простирается 1

У каждого пула есть:

Ключ Значения По умолчанию
name имя, которое используют его блоки соединения, например hamlet/streets —
pieces [{ file, weight, follows_ground }]. follows_ground: true изгибает часть по земле под ней, для улиц и троп; false оставляет её прямой, для домов вес 1, false
features [{ id, weight }]: фича в роли части, твоя или игровая (minecraft:chorus_plant) —
none вес отсутствия части вообще, для пустого участка 0
fallback пул, который используется там, где ни одна часть не подходит, например в конце улицы ничего
skip, replace как у одиночной структуры. В пуле у замены может быть where: только там, где в мире уже есть этот блок (кирпичи улицы над водой становятся досками) —

Все части остаются в пределах 80 блоков от первой.

Два параметра пока есть только в Kotlin: salt, число, которое выбирает, где в своём отрезке из spacing чанков окажется структура (две структуры с одинаковыми spacing и salt окажутся в одних и тех же местах; без него оно берётся из id структуры), и aboveBottom, на сколько блоков выше низа мира должны оставаться её части (где какая-то опустилась бы ниже, структура не создаётся).

Структуры, которые твой код строит блок за блоком, описаны на странице Генерация кодом.

Биомы

Собственный биом занимает часть мест игрового биома. Он сохраняет то, что там растёт, живёт и прорыто, и приносит свой климат и свои цвета.

content/ruby_meadow.craftCraftScript
biome "ruby_meadow" {
    replaces: "minecraft:plains"
    share: 0.5
    temperature: 0.8
    downfall: 0.4
    precipitation: true
    grass_color: "#d05070"
    foliage_color: "#c04060"
    sky_color: "#ff9fb0"
    fog_color: "#ffd0d8"
    water_color: "#ff6080"
    water_fog_color: "#a03050"
}
Свойство Значения По умолчанию
replaces игровой биом, чьи места он занимает: "minecraft:plains" "minecraft:plains"
share доля этих мест, которую он занимает, больше 0 и до 1 0.5
temperature температура климата 0.8
downfall сколько идёт осадков 0.4
precipitation true — идёт дождь, false — нет true
grass_color цвет травы, #rrggbb как у заменяемого биома
foliage_color цвет листвы как у заменяемого биома
sky_color цвет неба как у заменяемого биома
fog_color цвет тумана как у заменяемого биома
water_color цвет воды #3f76e4
water_fog_color цвет тумана под водой как у заменяемого биома

share равномерно распределяется по местам, где был бы заменяемый биом: 0.5 занимает половину, каждое второе. Новый биом наследует то, что там растёт, живёт и прорыто (растительность, руды, пещеры, существа, музыка), и всё, что другие моды добавляют в этот биом. Не указанные цвета остаются как у заменяемого биома.

Несколько биомов могут заменять один и тот же: они делят его места. Найти свой можно командой /locate biome <id мода>:ruby_meadow.

Звук, земля и существа

У биома может быть и своя музыка и свой воздух, его земля может покрываться твоим блоком, и ты можешь выбрать, кто там живёт:

content/glow_marsh.craftCraftScript
biome "glow_marsh" {
    replaces: "minecraft:swamp"
    share: 0.4
    music: "mymod:music.marsh"
    ambient_sound: "mymod:ambient.marsh_hum"
    particle: { id: "minecraft:glow", chance: 0.005 }
    surface: "mymod:glow_moss"
    spawns: [
        { creature: "minecraft:frog", weight: 10, group: [2, 5] },
        { creature: "mymod:marsh_wisp", weight: 4, group: [1, 2] },
    ]
}
Свойство Значения По умолчанию
music id звука, который играет как музыка биома как у заменяемого биома
ambient_sound звук, который там играет не переставая (ветер, гудение) как у заменяемого биома
particle { id, chance }: частица, парящая в его воздухе; chance — на каждую точку рядом с игроком за тик (0.001 — это немного) как у заменяемого биома; chance 0.01
surface блок, которым покрыта его земля (верхний блок каждого пола) обычная земля измерения
spawns [{ creature, weight, group }]: существа, которые там живут; если указано хоть одно, то именно эти и никакие другие как у заменяемого биома; weight 10, group [1, 4]
inherits false: там создаётся только то, что дано этому биому (его features, его carvers, то, что в него ставят моды), а не то, что создаётся в заменяемом биоме true
features [{ id, step }]: уже существующие фичи, игровые или из данных, которые в нём ставятся. step — это lakes, surface, ores, underground или vegetation —
carvers id карверов, которые выдалбливают его пещеры, твоих или игровых; они выполняются в указанном порядке, раньше карверов заменяемого биома —

С inherits: false биом всё равно занимает места заменяемого биома, а также его существ и звуки, если не задать свои; перестаёт приходить только то, что там растёт и прорыто. Земля, созданная блок за блоком, и собственные карверы описаны на странице Генерация кодом.

Биомы Края

В Краю биом занимает целые области шириной около 200 блоков, а не климатические места. Заменяя minecraft:end_highlands, он занимает всю островную сушу своих областей (высокогорья, средние земли и пустоши); заменяя minecraft:small_end_islands — пустоту между островами. Центральный остров остаётся игровым, а области в каждом мире разные.

content/crystal_glade.craftCraftScript
biome "crystal_glade" {
    replaces: "minecraft:end_highlands"
    share: 0.3
    sky_color: "#2a1840"
    fog_color: "#3c2a5a"
    surface: "mymod:crystal_moss"
    inherits: false
    features: [{ id: "minecraft:end_gateway_return", step: "surface" }]
}

Полезно знать

  • Только новые чанки. Уже сгенерированные чанки не меняются; руды, деревья, растения, структуры и биомы появляются только в чанках, сгенерированных после установки мода. Исследуй новую местность, чтобы найти их.
  • Отсутствующие имена пропускаются. Биом или тег в biomes, которого не существует (скажем, из другого мода, который не установлен), пропускается, а не вызывает ошибку.
  • Нет земли — нет структуры. Структура, стоящая на поверхности, не создаётся там, где в её столбце вообще нет земли, например в пустоте между островами Края.
  • Фичи, структуры, рельеф, карты биомов, карверы и земля, написанные кодом, описаны на странице Генерация кодом.
  • Целые собственные миры описаны на странице Измерения.

На Kotlin

content/World.ktKotlin
ore("ruby_ore") {
    replaces = OreHost.STONE_AND_DEEPSLATE
    size = 9
    perChunk = 8
    minY = -60
    maxY = 60
}

ore("void_ore") {
    replaces = OreHost.END_STONE
    biome("mymod:crystal_glade")
}

tree("ruby_tree") {
    trunk = "ruby_log"
    leaves = "ruby_leaves"
    height = 6
    perChunk = 2
    biome("#minecraft:is_forest")
}

block("ruby_flower") { plant = true }

patch("ruby_flowers") {
    block = "ruby_flower"
    rarity = 4
    biome("#minecraft:is_overworld")
}

structure("old_ruins") {
    variant("ruins_small", weight = 3)
    variant("ruins_tower")
    biome("#minecraft:is_forest")
    spacing = 20
    offsetY = -2
    skip("minecraft:air")
    replace("minecraft:stone_bricks", "minecraft:cracked_stone_bricks", chance = 0.3)
    decay(0.8, "minecraft:stone_bricks", "minecraft:cracked_stone_bricks")
    salt = 120457
}

structure("hamlet") {
    biome("minecraft:plains")
    spacing = 34
    depth = 6
    pool("hamlet/square") { piece("hamlet/square") }
    pool("hamlet/streets") {
        piece("hamlet/street_straight", weight = 3, followsGround = true)
        piece("hamlet/street_corner", followsGround = true)
        fallback = "hamlet/street_ends"
        replace("minecraft:stone_bricks", "minecraft:oak_planks", where = "minecraft:water")
    }
    pool("hamlet/street_ends") { piece("hamlet/street_end", followsGround = true) }
    pool("hamlet/houses") {
        piece("hamlet/house_small", weight = 4)
        piece("hamlet/house_big")
        none = 2
    }
}

biome("glow_marsh") {
    replaces = "minecraft:swamp"
    share = 0.4
    music = "mymod:music.marsh"
    ambientSound = "mymod:ambient.marsh_hum"
    particle("minecraft:glow", chance = 0.005)
    surface = "mymod:glow_moss"
    spawn("minecraft:frog", weight = 10, group = 2..5)
}

biome("crystal_glade") {
    replaces = "minecraft:end_highlands"
    share = 0.3
    surface = "mymod:crystal_moss"
    inherits = false
    feature("minecraft:end_gateway_return", FeatureStep.SURFACE)
}