API

코드로 생성하기

선언만으로 부족할 때는, 청크가 만들어지는 동안 여러분의 코드가 월드를 짓습니다. 피처, 구조물 전체, 땅의 모양, 어느 곳에 어떤 바이옴을 둘지, 동굴, 지면의 블록까지 다룰 수 있습니다.

쓸 수 있는 것

대상 Kotlin CraftScript
피처: 뾰족한 기둥, 벽에 붙는 식물, 바위 등 청크에 놓이는 모든 것 feature("…") { place { } } 없음
여러 청크에 걸치는, 코드로 짓는 구조물 structure("…") { plan { }; build { } } 있음(plan, build)
차원의 땅 terrain("minecraft:the_end") { } 있음(terrain)
어느 곳에 어떤 바이옴을 둘지 biomes("minecraft:the_end") { } 있음(biome_map)
카버: 동굴과 터널 carver("…", chance) { } 있음(carver)
블록 단위로 만드는 바이옴의 지면 biome("…") { surface { } } 있음(surface: fun(at))
블록, 아이템, 바이옴의 태그 tag(TagKind.BIOME, "…", …) 없음

이 페이지의 모든 코드는 청크가 만들어지는 동안 여러 스레드에서 동시에 실행됩니다. 직접 만든 난수 대신 주어지는 난수(또는 월드의 시드)를 쓰세요. 그러면 같은 시드는 같은 월드를 만듭니다. Kotlin에서는 호출 사이에 공유하는 것을 스레드에 안전하게 유지하세요. CraftScript에서는 random 멤버를 쓸 수 없으므로, 변화는 좌표, 시드, 구조물의 사이트에서 얻으세요.

피처

피처는 만들어지고 있는 청크 안에서, 여러분이 나열한 바이옴에 코드가 짓는 것입니다. 게임이 자체 피처에 하듯 장소는 Crafting이 고르고, 여러분의 place 함수가 그곳에 짓고 무언가를 지었으면 true를 반환합니다. 피처는 Kotlin으로 작성합니다.

content/CrystalSpikes.ktKotlin
object CrystalSpikes {
    private val CRYSTAL = Identifier.parse("mymod:crystal")

    fun register(content: ContentBuilder) {
        content.feature("crystal_spike") {
            biome("#minecraft:is_overworld")
            count = 2..5
            heights = -54..30
            on = FeatureOn.FLOOR
            underground = true
            step = FeatureStep.UNDERGROUND
            place { world ->
                val (x, y, z) = Triple(world.x, world.y, world.z)
                if (!world.isIn(x, y - 1, z, "#minecraft:base_stone_overworld")) return@place false
                val height = 2 + world.random.nextInt(4)
                for (dy in 0 until height) {
                    if (!world.isAir(x, y + dy, z)) break
                    world.set(x, y + dy, z, CRYSTAL)
                }
                true
            }
        }
    }
}
옵션 값 기본값
biome(…) 놓일 바이옴, id 또는 #tag. 최소 하나 —
count 청크당 시도 횟수, 범위: 2..5 1..1
chance 이 수만큼의 청크마다 한 청크에서만 1
heights 각 시도를 이 범위의 임의 높이에서 수행 null: 월드의 바닥(자리는 코드가 찾음)
spread true: 각 시도를 청크의 임의 열에서. false: 청크의 모서리에서, 거기서부터 코드가 고름 true
on FeatureOn.FLOOR 또는 CEILING: 그 높이에서 최대 32블록 떨어진 가장 가까운 바닥 또는 천장 옆의 공기로 옮겨집니다. 없으면 놓이지 않습니다 null
underground true: 지표 아래, 최소 2블록 아래(동굴 안)에서만 false
everyFloor true: 고른 각 열의 모든 바닥, 즉 지표와 각 동굴의 바닥에서. count는 바닥당 열의 수 false
tries everyFloor와 함께: 바닥을 몇 번 훑는지. 매번 각 바닥에 count개의 열이 더해지므로, 깊은 땅에도 더 많은 시도가 닿습니다 1..1
step 청크를 채우는 단계 중 언제 만들어지는지: LAKES, SURFACE, ORES, UNDERGROUND(동굴을 꾸미는 것), VEGETATION VEGETATION

everyFloor에서는 chance, heights, spread를 쓰지 않습니다. 장소가 바닥 그 자체이기 때문입니다.

content/GlowTufts.ktKotlin
content.feature("glow_tufts") {
    biome("mymod:crystal_glade")
    everyFloor = true
    count = 4..8
    tries = 1..3
    place { world ->
        val tuft = Identifier.parse("mymod:glow_tuft")
        if (world.structures(world.x, world.z).isNotEmpty()) return@place false
        world.canStay(world.x, world.y, world.z, tuft) && world.set(world.x, world.y, world.z, tuft)
    }
}

피처가 보는 것

place는 만들어지고 있는 월드를, 피처가 놓이는 곳에서 본 모습으로 받습니다. 만들어지고 있는 청크와 그 주변 청크를 읽고 쓸 수 있으며, 그 바깥에 쓰는 것은 건너뜁니다. CraftScript(구조물의 build 안)에서는 같은 멤버를 snake_case로 씁니다.

멤버 설명
x, y, z 놓이는 위치
random 전용 난수: 같은 시드는 같은 피처를 만듭니다
seed 월드의 시드. 월드 전체에서 같은 노이즈를 위해
minY, maxY 월드의 높이. 블록은 minY부터 maxY 바로 아래까지
block(x, y, z), state(x, y, z, name), isAir(x, y, z) 그 자리의 블록, 그 상태 하나의 값, 공기인지 여부
isIn(x, y, z, tag) 그 자리의 블록이 태그("#minecraft:leaves")에 속하는지, 또는 그 블록("minecraft:end_stone")인지
canStay(x, y, z, block, states) 그 상태의 블록이 그 자리에 있을 수 있는지: 땅 위의 식물, 바깥을 향한 벽의 이끼 등. states는 생략할 수 있습니다
set(x, y, z, block, states) 블록을 설정합니다. 상태는 mapOf("facing" to "north")처럼 줍니다. 설정할 수 있는 범위 밖이거나 여기서 블록이 아니면 false
inside(x, z) 그 열이 읽고 쓸 수 있는 열인지
surface(x, z) 공기가 아닌 가장 높은 블록 위의 첫 블록. 피처가 놓이기 전의 땅 기준
top(x, z) 같은 것을, 그 뒤에 피처가 설정한 것까지 포함한 지금의 상태로
flow(x, y, z) 청크가 월드에 들어간 뒤 그곳의 물(또는 용암, 물을 머금은 블록)이 흐르게 합니다. 청크가 만들어지는 동안 설정한 물은 가만히 있어서, 이것이 없으면 공기 옆에 매달려 있게 됩니다
structures(x, z) 그 열의 청크를 영역에 포함하는 구조물(minecraft:end_city 같은 id). 피처를 그 안에 두지 않기 위해 씁니다
placeFile(file, x, y, z, rotation, mirror, pivotX, pivotZ) 구조물 파일을 놓습니다. 코드에서 쓰는 구조물 파일 참고

피처가 지정한 블록이 존재하지 않으면(설치되지 않은 모드의 블록 등) 제외되며 로그에 경고가 한 번 남습니다. 그 블록에 대해 set은 false를 반환합니다.

코드로 짓는 구조물

파일로 만들 수 없거나 땅을 따라야 하는 구조물은, 코드가 어디에 둘지 정하고 짓습니다. 함수 두 개가 필요합니다.

  • **plan**은 월드가 구조물 하나를 놓을 만한 청크마다(biomes, spacing, separation에 따라, 다른 구조물과 같습니다), 그 청크의 블록이 만들어지기 전에 거기에 있는지 질문받습니다. 사이트, 즉 중심, 미치는 범위, 짓는 데 필요한 것을 반환합니다. 아무것도 반환하지 않으면 그곳에는 없는 것입니다.
  • **build**는 사이트가 덮는 각 청크 안의 부분을 한 번에 한 청크씩 짓습니다. 모든 청크가 같은 사이트와 같은 난수를 받으므로, 각 청크는 같은 구조물의 자기 조각을 짓습니다. 사이트는 월드와 함께 저장되므로, 재시작 뒤에 만들어지는 청크도 맞물립니다.
content/stone_ring.craftCraftScript
structure "stone_ring" {
    biomes: ["#minecraft:is_overworld"]
    spacing: 32
    separation: 12
    plan: fun(p) {
        let x = p.chunk_x * 16 + 8
        let z = p.chunk_z * 16 + 8
        let y = p.height(x, z)
        return { x: x, y: y, z: z, radius: 10, min_y: y - 8, max_y: y + 12 }
    }
    build: fun(world, site) {
        for i in 0..15 {
            let a = i * pi() / 8
            let x = site.x + round(cos(a) * 10)
            let z = site.z + round(sin(a) * 10)
            if world.inside(x, z) {
                let ground = world.surface(x, z)
                for dy in 0..2 { world.set(x, ground + dy, z, "minecraft:mossy_cobblestone") }
            }
        }
    }
}
content/StoneRing.ktKotlin
content.structure("stone_ring") {
    biome("#minecraft:is_overworld")
    spacing = 32
    separation = 12
    plan { p ->
        val x = p.chunkX * 16 + 8
        val z = p.chunkZ * 16 + 8
        val y = p.height(x, z)
        StructureSite(x, y, z, radius = 10, minY = y - 8, maxY = y + 12,
            data = mapOf("tall" to p.random.nextBoolean()))
    }
    build { world, site ->
        val stone = Identifier.parse("minecraft:mossy_cobblestone")
        val top = if (site.data["tall"] == true) 4 else 2
        for (i in 0 until 16) {
            val x = site.x + (cos(i * PI / 8) * 10).roundToInt()
            val z = site.z + (sin(i * PI / 8) * 10).roundToInt()
            if (!world.inside(x, z)) continue
            val ground = world.surface(x, z)
            for (dy in 0..top) world.set(x, ground + dy, z, stone)
        }
    }
}

사이트(Kotlin에서는 StructureSite, CraftScript에서는 맵):

필드 설명 CraftScript 기본값
x, y, z 중심 0
radius 중심 둘레로 몇 블록까지 미치는지: 덮는 청크를 정합니다 8
min_y, max_y(minY, maxY) 덮는 높이 y에서 radius를 뺀 값과 더한 값
data 각 청크에서 똑같이 짓기 위해 build에 필요한 것: 숫자, 텍스트, 참 또는 거짓 비어 있음

Kotlin에서는 사이트에 그 위치로 만든 seed도 있습니다. data의 숫자는 재시작 뒤 소수로 돌아옵니다. (site.data["n"] as Number).toInt()로 읽으세요.

청크의 블록이 하나도 만들어지기 전에 plan이 받는 것:

멤버 설명
chunkX, chunkZ 질문받는 청크(블록 / 16)
seed, random 월드의 시드와, 이 자리 전용 난수
height(x, z) 그곳에서 지표가 갖게 될 높이(그 위의 첫 블록)
biome(x, y, z) 그 자리의 바이옴
column(x, z), minY 그 열에서 땅이 갖게 될 블록. minY부터 월드의 꼭대기까지, 지면, 동굴, 지어지는 것보다 앞선 상태(엔드에서는 엔드 돌과 공기)
fileSize(file) 구조물 파일의 크기(x, y, z). 파일이 없으면 null

build는 피처와 같은 월드를 받지만, 짓고 있는 청크의 블록만 설정할 수 있고 그 random은 사이트에서 옵니다. 여기에 해당하는 구조물의 다른 옵션은 biomes, spacing, separation, 그리고 Kotlin에서는 salt입니다. 코드 구조물에는 plan과 build가 모두 필요합니다. 다른 구조물과 마찬가지로 /locate structure로 찾을 수 있습니다.

코드에서 쓰는 구조물 파일

placeFile은 코드가 말한 자리에, 회전하고 뒤집어서 구조물 파일을 놓습니다. 코드 구조물 안에 여러분의 파일로 만든 탑을 두거나, 피처가 동굴에 폐허를 떨어뜨리는 식입니다. 파일은 모드의 structures/<path>.nbt("mymod:watchtower") 또는 게임의 것입니다. 월드가 설정할 수 있는 범위 안쪽 부분만 놓이므로, 여러 청크에 걸치는 구조물은 각 청크에서 파일을 놓습니다. 파일 안의 구조 블록은 놓이지 않습니다. 그런 파일이 없으면 false를 반환합니다.

content/Watchtower.ktKotlin
val TOWER = Identifier.parse("mymod:watchtower")

content.structure("watchtower") {
    biome("minecraft:plains")
    spacing = 40
    separation = 10
    plan { p ->
        val size = p.fileSize(TOWER) ?: return@plan null
        val x = p.chunkX * 16 + 8
        val z = p.chunkZ * 16 + 8
        val y = p.height(x, z)
        StructureSite(x, y, z, radius = maxOf(size.x, size.z), minY = y, maxY = y + size.y,
            data = mapOf("turns" to p.random.nextInt(4), "half_x" to size.x / 2, "half_z" to size.z / 2))
    }
    build { world, site ->
        val hx = (site.data["half_x"] as Number).toInt()
        val hz = (site.data["half_z"] as Number).toInt()
        // Its middle on the site, turned about its middle.
        world.placeFile(TOWER, site.x - hx, site.y, site.z - hz,
            rotation = (site.data["turns"] as Number).toInt(), pivotX = hx, pivotZ = hz)
    }
}
매개변수 값 기본값
file 파일의 id —
x, y, z 회전하기 전, 그 모서리가 놓일 자리 —
rotation 시계 방향 90도 회전 횟수 0
mirror Mirror.NONE, LEFT_RIGHT(z 축을 따라) 또는 FRONT_BACK(x 축을 따라) NONE
pivotX, pivotZ 회전의 중심이 되는 파일 안의 블록 0, 0

차원의 땅

게임의 차원(minecraft:overworld, minecraft:the_nether, minecraft:the_end) 중 하나의 땅 모양을 정할 수 있습니다. 떠 있는 섬, 완만한 언덕, 기둥의 세계 같은 것입니다. 여러분의 모양은 각 지점이 얼마나 단단한지 알려 줍니다. 0보다 크면 땅, 0보다 작으면 공기입니다. 땅은 그 차원의 평소 돌로 이루어지고, 그 위에 바이옴의 지면이 올라갑니다.

content/hills.craftCraftScript
// Rolling hills over the whole overworld.
terrain "minecraft:overworld" {
    column: fun(x, z, ys, world) {
        let ground = 72 + 14 * sin(x / 60) * cos(z / 60)
        return ys.map(fun(y) { return (ground - y) / 8 })
    }
    has_land: fun(x, z, world) { return true }
}
content/FloatingIslands.ktKotlin
// Round, flattened islands in the End, one every 96 blocks.
content.terrain("minecraft:the_end") { world ->
    val shift = kotlin.random.Random(world.seed).nextInt(96)
    object : TerrainShape {
        fun across(x: Int, z: Int): Double {
            val dx = (x + shift).mod(96) - 48
            val dz = (z + shift).mod(96) - 48
            return sqrt((dx * dx + dz * dz).toDouble())
        }
        override fun column(x: Int, z: Int, ys: IntArray, out: DoubleArray) {
            val flat = across(x, z)
            for (i in ys.indices) {
                val up = (ys[i] - 64) * 2.5
                out[i] = (24 - sqrt(flat * flat + up * up)) / 24
            }
        }
        override fun hasLand(x: Int, z: Int) = across(x, z) < 24
    }
}
멤버 설명
column(x, z, ys, out) 열 x, z가 ys의 각 높이에서 얼마나 단단한지를 같은 순서로 out에 넣습니다. CraftScript에서는 column(x, z, ys, world)가 리스트를 반환합니다
hasLand(x, z)(has_land) 그 열에 땅이 있는지. 엔드에서는 땅 바이옴과 허공의 바이옴 중 어느 쪽인지를 정합니다
world.seed 월드의 시드
world.minY, world.height 땅이 만들어지는 높이: minY부터 위로 height블록
world.biome(x, y, z) 한 블록의 바이옴

게임은 너비가 몇 블록인 셀의 모서리에서 여러분의 모양을 묻고 그 사이를 섞으므로, 블록 단위로 정확할 필요는 없습니다. Kotlin에서는 함수가 월드당 한 번, 시드와 함께 호출되어 모양을 반환합니다. 여러분의 모양이 땅 전체를 만듭니다. 게임 자체의 노이즈 동굴은 만들어지지 않으며(카버를 추가하세요), 엔드에서는 중앙 섬도 여러분이 만들어야 합니다. 한 차원의 모양을 만들 수 있는 모드는 하나뿐입니다. 실패한 모양은 로그에 한 번 알려지며 그곳에 땅을 만들지 않습니다. 충돌하지는 않습니다.

자신만의 차원은 게임의 지형 중 하나를 골라 차원 페이지에서 선언합니다.

어느 곳에 어떤 바이옴을 둘지

기본적으로 바이옴은 자신이 대체하는 바이옴의 자리 중 share만큼을 가져갑니다(월드 생성 참고). 자신만의 지도를 만들려면, 각 지점의 바이옴을 코드가 고릅니다. 지금은 엔드(minecraft:the_end)용입니다.

content/end_map.craftCraftScript
biome_map "minecraft:the_end" {
    biome: fun(x, y, z, land, world) {
        if x * x + z * z < 65536 { return "minecraft:the_end" }      // the central island
        if land == "minecraft:end_highlands" and (floor(x / 64) + floor(z / 64)) % 2 == 0 {
            return "mymod:crystal_glade"
        }
        return land
    }
}
content/EndMap.ktKotlin
content.tag(TagKind.BIOME, "glades", "crystal_glade", "ember_glade")

content.biomes("minecraft:the_end") { world ->
    val glades = world.tagged("mymod:glades")
    val theEnd = Identifier.parse("minecraft:the_end")
    BiomeMap { x, y, z, land ->
        when {
            x.toLong() * x + z.toLong() * z < 256L * 256 -> theEnd            // within 1024 blocks
            land.path != "end_highlands" || glades.isEmpty() -> land
            else -> glades[Math.floorMod((x shr 6) * 31 + (z shr 6), glades.size)]
        }
    }
}

함수는 쿼트 단위의 x, y, z(게임은 4×4×4 블록마다 바이옴 하나를 둡니다. 1쿼트는 블록 / 4)와, land, 즉 그곳에서 게임의 노이즈가 만드는 땅의 종류를 바이옴으로 받습니다: minecraft:end_highlands, end_midlands, end_barrens 또는 small_end_islands. 자신만의 모양이 있으면 땅 위에서는 end_highlands, 땅 밖에서는 small_end_islands입니다. 중앙 섬에서도 land를 받으며, 그곳은 지도가 직접 놓습니다. 게임은 중심에서 1024블록 이내에 minecraft:the_end를 둡니다.

답은 엔드의 바이옴이어야 합니다. 게임의 것, 또는 replaces를 엔드 바이옴으로 하여 선언한 여러분의 것입니다. 다른 답이나 실패한 지도는 게임의 선택으로 돌아갑니다(로그에 한 번 알림). 지도의 world에는 seed와 tagged(tag), 즉 바이옴 태그에 속한 바이옴이 있습니다. 한 차원의 바이옴을 고를 수 있는 모드는 하나뿐입니다.

카버

카버는 땅이 만들어진 뒤, 지면과 피처보다 앞서 동굴을 파냅니다. 만들어지고 있는 청크마다 게임은 그 주변의 청크(각 방향 8개)를 훑습니다. 각 청크에서 그 청크 바이옴의 모든 카버가 chance(0–1)로 시작하고, 여러분의 함수가 만들어지고 있는 청크 중 파낼 곳을 표시합니다. 파낸 블록은 공기(대수층 아래에서는 물)가 되고, 그 위에 지면이 다시 만들어집니다. 바이옴은 carvers에 카버의 이름을 적어 사용합니다.

content/round_caves.craftCraftScript
// A round room, 6 blocks across, in some chunks.
carver "round_caves" {
    chance: 0.05
    carve: fun(ctx) {
        let cx = ctx.start_x * 16 + 8
        let cz = ctx.start_z * 16 + 8
        let cy = 20
        for x in cx - 6..cx + 6 {
            for y in cy - 6..cy + 6 {
                for z in cz - 6..cz + 6 {
                    if (x - cx) * (x - cx) + (y - cy) * (y - cy) + (z - cz) * (z - cz) <= 36 { ctx.carve(x, y, z) }
                }
            }
        }
    }
}

biome "hollow_hills" {
    replaces: "minecraft:meadow"
    carvers: ["round_caves"]
}
content/RoundCaves.ktKotlin
content.carver("round_caves", chance = 0.05) { ctx ->
    val r = ctx.random
    val cx = ctx.startX * 16 + r.nextInt(16)
    val cz = ctx.startZ * 16 + r.nextInt(16)
    val cy = r.nextInt(ctx.minY + 10, 40)
    val radius = r.nextInt(4, 9)
    for (x in cx - radius..cx + radius) for (y in cy - radius..cy + radius) for (z in cz - radius..cz + radius) {
        val (dx, dy, dz) = Triple(x - cx, y - cy, z - cz)
        if (dx * dx + dy * dy * 2 + dz * dz <= radius * radius) ctx.carve(x, y, z)
    }
}

content.biome("hollow_hills") {
    replaces = "minecraft:meadow"
    carver("round_caves")
}
멤버 설명
startX, startZ 이 동굴이 시작하는 청크(청크 좌표: 블록 / 16)
chunkX, chunkZ 만들어지고 있는 청크
minY, maxY 파낼 수 있는 높이, 양끝 포함
seed, random 월드의 시드와 이 시작점의 난수: 시작점이 질문되는 모든 청크에서 같은 값을 뽑으므로, 청크를 가로지르는 동굴도 이어집니다
carve(x, y, z) 그 블록을 월드 좌표로 파냅니다. 만들어지고 있는 청크 밖의 블록은 건너뜁니다

동굴은 시작한 곳에서 최대 8청크까지 닿을 수 있습니다. CraftScript에서 chance의 기본값은 1입니다. 실패한 카버는 그곳에서 아무것도 파내지 않으며, 로그에 한 번 알려집니다.

바이옴의 지면

surface는 바이옴의 지면을 블록 하나로 덮습니다. 층, 얼룩, 비탈을 만들려면 대신 함수를 주세요. 청크가 만들어지는 동안 게임은 바이옴 지면의 각 블록에 대해, 위에서 아래로, 그 자리에 어떤 블록을 둘지 묻습니다. 답이 없으면 그 블록은 차원(그 돌)에 맡겨집니다.

content/crystal_glade.craftCraftScript
biome "crystal_glade" {
    replaces: "minecraft:end_highlands"
    share: 0.3
    surface: fun(at) {
        if at.depth_above == 1 { return "mymod:crystal_moss" }
        if at.depth_above <= 3 { return "mymod:crystal_soil" }
        return null
    }
}
content/CrystalGlade.ktKotlin
content.biome("crystal_glade") {
    replaces = "minecraft:end_highlands"
    share = 0.3
    surface { at ->
        val patch = at.noise("minecraft:surface", at.x.toDouble(), 0.0, at.z.toDouble()) > 0.2
        when {
            at.depthAbove == 1 && patch -> Identifier.parse("mymod:glow_moss")
            at.depthAbove == 1 -> Identifier.parse("mymod:crystal_moss")
            at.depthAbove <= 3 -> Identifier.parse("mymod:crystal_soil")
            else -> null
        }
    }
}
at의 멤버 설명
x, y, z 질문받는 블록
depthAbove(depth_above) 위의 열린 공기에서 이 블록까지의 지면 블록 수: 지면의 맨 위 블록이나 동굴 바닥에서는 1
depthBelow(depth_below) 이 블록에서 아래의 열린 공기까지의 지면 블록 수: 동굴이나 허공 위의 가장 낮은 블록에서는 1
surfaceDepth(surface_depth) 이 열의 표층이 얼마나 깊은지. 게임이 달리하는 값
steep 게임의 산이 민둥 돌을 드러내는 곳만큼 지면이 기울었는지
noise(id, x, y, z) 월드의 노이즈 중 이름으로 고른 하나("minecraft:surface"). 시드로 만들어진 그대로

함수는 surface보다 먼저 적용됩니다. 함수가 아무 답도 내지 않은 곳에서는, 함께 지정한 surface 블록이 여전히 맨 위를 덮습니다. 실패한 함수는 한 번만 알려지며, 실패한 곳에서는 차원의 지면이 쓰입니다.

태그

태그는 블록, 아이템, 바이옴을 하나의 이름으로 묶어서, 피처가 isIn(x, y, z, "#mymod:crystal_ground")를 검사하고 바이옴 목록이 "#mymod:glades"라고 쓸 수 있게 합니다. 모드는 자신의 태그에도, 게임의 것 같은 누구의 태그에도 추가할 수 있습니다.

content/Tags.ktKotlin
// Blocks a crystal can grow on, yours and the game's.
content.tag(TagKind.BLOCK, "crystal_ground", "crystal_moss", "crystal_soil", "minecraft:end_stone")
// Biomes a feature or structure can name as "#mymod:glades".
content.tag(TagKind.BIOME, "glades", "crystal_glade", "ember_glade")
// Adding to the game's: a pickaxe mines it faster.
content.tag(TagKind.BLOCK, "minecraft:mineable/pickaxe", "crystal_soil")

TagKind는 BLOCK, ITEM, BIOME 중 하나입니다. 값은 id 또는 #tags이며, 네임스페이스가 없는 이름은 모드의 것입니다. 여러 모드가 같은 태그에 추가할 수 있고, 존재하지 않는 값은 오류가 아니라 제외됩니다.

알아 두면 좋은 점

  • 새 청크만 코드가 만든 것을 받습니다. 월드 생성의 모든 것과 같습니다.
  • 오류가 월드를 멈추지 않습니다. 예외를 던진 코드는 그곳에서 만들던 것을 제외하고, 오류는 로그에 기록됩니다.
  • 가볍게 유지하세요. 이 코드는 모든 청크마다 실행되며, 플레이어가 탐험하는 동안 수천 번 호출됩니다. 무거운 작업은 피하고, CraftScript에서는 레퍼런스의 단계 수 제한을 염두에 두세요.