API

ブロック、アイテム、レシピ

コンテンツはプロパティの一覧として宣言します。Crafting が適切なタイミングで本物のゲームオブジェクトを作り、必要なモデル、ルートテーブル、タグ、レシピ、翻訳を生成します。ゲームのデータファイルを書く必要はありません。

アイテム

content/items.craftCraftScript
item "ruby" { rarity: "rare" }

item "ruby_apple" {
    food: { nutrition: 8, saturation: 1.2, always_edible: true }
    glint: true
}

item "ruby_pickaxe" { tool: { type: "pickaxe", tier: "diamond", speed: 9 }, tab: "tools_and_utilities" }
プロパティ 値 デフォルト
stack または max_stack 1–99 64
rarity common、uncommon、rare、epic(名前の色) common
glint エンチャントの輝き false
durability 数値。stack: 1 が強制されます 0
fireproof 溶岩や火で燃えない false
food 数値、または { nutrition, saturation, always_edible } —
tool "pickaxe"、または { type, tier, damage, speed }。type:pickaxe、axe、shovel、hoe、sword —
tab クリエイティブインベントリのタブ(下記) ingredients
texture テクスチャのパス item/<id>
on_use fun(player, stack)。使用を処理した場合は true を返します —
armor { slot, defense, toughness, knockback_resistance, texture } —
on_hit fun(attacker, target, stack) —
cooldown 秒 0

防具、武器、クールダウン

armor を持つアイテムは身に着けられます。slot は head、chest、legs、feet のいずれかです。defense、toughness、knockback_resistance(0〜1)はゲームの防具の値で、鉄のチェストプレートは防御 6、ダイヤモンドは靭性 2 です。

content/armor.craftCraftScript
item "frost_helmet" { texture: "minecraft:item/iron_helmet", armor: { slot: "head", defense: 3, texture: "frost" } }
item "frost_chestplate" { armor: { slot: "chest", defense: 8, toughness: 2 }, durability: 400 }

texture は身に着けたときの見た目です。frost は、Mod 内の textures/entity/equipment/humanoid/frost.png、脚用には textures/entity/equipment/humanoid_leggings/frost.png を指し、ゲームの防具テクスチャと同じ配置です。指定しない場合は鉄の防具のように見えます。

on_hit は、プレイヤーでもモブでも、そのアイテムで攻撃したときに実行されます。

content/frost_blade.craftCraftScript
item "frost_blade" {
    texture: "minecraft:item/diamond_sword"
    tool: "sword"
    cooldown: 3
    on_hit: fun(attacker, target, stack) {
        target.add_effect("minecraft:slowness", 4, 4)
        target.world.spawn_particle("minecraft:snowflake", target.location.add(0, 1, 0), 20, 0.4, 0.02)
    }
}

cooldown(秒)は、on_use が処理した使用のたびに、その時間だけアイテムを使えなくし、ホットバーに表示されます。コードからは player.set_cooldown("minecraft:feather", 2) と player.has_cooldown(id) を使います。Kotlin では、防具は armor(EquipmentSlot.HEAD, defense = 3, texture = "frost")、武器は onHit = { ctx -> … }(ctx.attacker、ctx.target、ctx.stack)です。

content/Armor.ktKotlin
item("frost_helmet") { armor(EquipmentSlot.HEAD, defense = 3, texture = "frost") }

ブロック

content/ores.craftCraftScript
block "ruby_ore" {
    hardness: 3
    tool: "pickaxe"
    tier: "iron"
    loot: [
        { item: "rubies:ruby", count: [1, 2] },
        { item: "minecraft:diamond", chance: 0.1 }
    ]
}

block "ruby_block" { hardness: 5, light: 7, tool: "pickaxe", sound: "metal" }

block "ruby_lamp" { hardness: 0.3, light: 15, sound: "glass", transparent: true, tab: "functional_blocks" }

block "ruby_bricks" { hardness: 2, tool: "pickaxe", drops: "ruby", drop_count: [2, 4] }
プロパティ 値 デフォルト
hardness 数値。-1 = 破壊不可 1.5
resistance 爆発耐性 = hardness
light 0–15 0
light_when トグルのステート("lit" など):オンの間だけブロックが光ります(ブロックステートを参照) 常に
sound stone、wood、gravel、grass、metal、glass、wool、sand stone
like 同じように作るブロック。ゲームのもの("minecraft:end_stone")でも自分のものでも、硬さ、爆発耐性、サウンド、何かをドロップさせるのに適切なツールが必要かどうかが、そのブロックのものになります —
kind ゲームの種類のどれか:階段、ドア、チェスト、作物…(ブロックの種類を参照) cube
tool、tier ブロックが何かをドロップするために必要なツールと、そのツールの最低限の素材:wood、stone、iron、diamond、netherite —、wood
drops、drop_count アイテム 1 種類:id。数値または [min, max] ブロック自身、1
loot 複数のアイテム:[{ item, count, chance, tool, fortune }, …]。それぞれ個別に抽選されます。count は数値または [min, max]、chance は 0 から 1(デフォルト 1)。tool と fortune:下のドロップを参照 —
friction 通常は 0.6、氷は 0.98 0.6
transparent 向こうが透けて見える(ガラス、葉) false
has_item ブロックのアイテムも登録する。アイテムがない場合、drops または loot で指定しない限り、ブロックは何もドロップしません true
tab クリエイティブインベントリのタブ building_blocks
on_use fun(player, block)。使用を処理した場合は true を返します。スニークしながら手に何か持っているプレイヤーは、ゲームのブロックと同じように、代わりにそれを設置します —

タブ:building_blocks、colored_blocks、natural_blocks、functional_blocks、redstone_blocks、tools_and_utilities、combat、food_and_drinks、ingredients、spawn_eggs。Kotlin では CreativeTabs にあります。

モブが倒れたときに追加で何かをドロップさせるには、entity_death イベントで e.drops に追加します(イベントを参照)。

立方体でないブロック、ゲームの種類のブロック、モブ、鉱石、サウンド、パーティクルも同じ方法で宣言し、それぞれ専用のページがあります:ブロックの形、ブロックの種類、モブ、ワールド生成、サウンドとパーティクル。

ドロップ:ツールと幸運

loot のドロップには、ツールを必要とさせたり、幸運でその量を増やしたりできます。

content/drops.craftCraftScript
block "ruby_ore" {
    kind: "ore"
    tool: "pickaxe"
    tier: "iron"
    xp: [1, 4]
    loot: [
        { item: "ruby", count: [1, 2], fortune: true },
        { item: "ruby_ore", tool: "silk_touch" }
    ]
}

block "frost_leaves" {
    kind: "leaves"
    loot: [
        { item: "frost_leaves", tool: "shears" },
        { item: "frost_sapling", chance: 0.05, fortune: true }
    ]
}
  • tool: "silk_touch":ブロックをシルクタッチで壊したときだけドロップします。tool: "shears":ゲームの葉やツタが自身をドロップするのと同じように、ハサミまたはシルクタッチのときだけです。
  • ツールが必要なドロップがあるとき、ツールなしのドロップは、そのツールを使わなかったときだけ起こります。上の鉱石は、シルクタッチなら自身を、それ以外ならルビーをドロップします。
  • fortune: true:幸運でより多くドロップします。ゲームの鉱石のように count が増えるか、葉から出る苗木のように chance が良くなります。

Kotlin では:drop("ruby", 1..2, tool = null, fortune = true) と drop("ruby_ore", tool = DropTool.SILK_TOUCH)。

content/Drops.ktKotlin
block("ruby_ore") {
    kind = BlockKind.ORE
    xp = 1..4
    drop("ruby", 1..2, tool = null, fortune = true)
    drop("ruby_ore", tool = DropTool.SILK_TOUCH)
}

レシピ

content/recipes.craftCraftScript
recipe shaped "ruby_block" {
    pattern: ["RRR", "RRR", "RRR"]
    keys: { R: "ruby" }
    result: "ruby_block"
}

recipe shapeless "rubies_from_block" { ingredients: ["ruby_block"], result: "ruby", count: 9 }

recipe smelting "ruby_from_ore" { input: "ruby_ore", result: "ruby", xp: 1.0 }

使用時の動作

on_use は、データの隣に置かれる唯一のロジックです。数行を超えるようなら、関数を lib/ に書いてインポートします。

content/wands.craftCraftScript
import { lift } from "/lib/teleport"

item "lift_wand" { stack: 1, rarity: "uncommon", on_use: lift }
lib/teleport.craftCraftScript
fun lift(player, stack) {
    player.teleport(player.location.add(0, 10, 0))
    return true
}

反応するブロック

ブロックは、自分自身や周囲で何かが起きたときにコードを実行できます。各ハンドラーはブロックと、必要に応じてエンティティを受け取ります。

プロパティ 実行されるとき
on_step: fun(block, entity) エンティティがブロックの上を歩いたとき。
on_inside: fun(block, entity) エンティティがブロックの中にいるとき。ブロックはエンティティを通す必要があります(ポータル、植物、ソリッドでない形状など)。
on_random_tick: fun(block) 作物の成長のように、ときどきランダムに。1ブロックあたり約68秒に1回です。
on_tick: fun(block) block.schedule(ticks) で指定した時間が経過したとき(20ティック = 1秒)。
on_neighbor_change: fun(block) 隣のブロックが変化したとき(設置、破壊、動力の付与)。
on_placed: fun(block, entity) 誰かがブロックを設置したとき。entity はその設置者。
content/reactions.craftCraftScript
block "jump_pad" { on_step: fun(b, e) { e.velocity = vector(0, 1.1, 0) } }

block "blinker" {
    light: 7
    on_tick: fun(b) {
        b.world.spawn_particle("minecraft:end_rod", b.location.add(0.5, 1.2, 0.5), 4, 0.1, 0.01)
        b.schedule(20)
    }
    on_neighbor_change: fun(b) { b.schedule(1) }
}

Kotlin では、ハンドラーは onStep、onInside、onRandomTick、onTick、onNeighborChange、onPlaced です。それぞれ block と、ある場合は entity を持つ BlockEventContext を受け取ります:

content/Reactions.ktKotlin
block("pad") { onStep = { ctx -> ctx.entity?.velocity = Vector(0.0, 1.1, 0.0) } }

ポータル

portal を持つブロックは、中にいる者を別のディメンションへ連れていきます。行き先のディメンションを指定するか、to と back で向こうからの行き先を選びます:

content/portals.craftCraftScript
block "sky_gate" { portal: "gatemod:sky", light: 11 }

block "sky_gate_two_way" { portal: { to: "gatemod:sky", back: "minecraft:overworld" } }

エンティティは同じ x と z の地面に到着し、そこで戻るためのポータルブロックを見つけます。近くにない場合は、到着地点の隣に1つ設置されます。エンティティは、再びポータルを使うまでしばらく待ちます。ポータルブロックはエンティティを通します。ディメンション自体は dimension で宣言します(@dim@ を参照)。Kotlin では:

content/Portals.ktKotlin
block("sky_gate") { portal("gatemod:sky") }

ブロックステート

states は、ブロックが記憶し、表示にも反映できる値を与えます:

content/states.craftCraftScript
block "lamp" {
    model: "block/lamp"
    states: ["facing", "lit"]
    on_use: fun(p, b) { b.set_state("lit", !b.state("lit")); return true }
    on_neighbor_change: fun(b) { b.set_state("lit", b.redstone_power > 0) }
}

block "crop" { states: [{ stage: 3 }, { wet: true }] }
  • "facing":北、東、南、西。設置したプレイヤーの方を向き、モデルも一緒に回ります。
  • "lit":名前だけならオン/オフのトグルで、デフォルトはオフです。{ lit: true } ならデフォルトがオンになります。
  • { stage: 3 }:0 から指定した最大値(1~15)までの数値。
  • "facing_all":"facing" と同じですが、上と下も向けます。設置したプレイヤーの方を向き、上下のときはモデルが倒れます。
  • { shape: ["top", "middle", "bottom"] }:いくつかの名前のうちの 1 つで、最初のものがデフォルトです。名前は小文字、数字、_ で書きます。

block.state("lit") で読み取り、block.set_state("lit", true) で変更します。ゲーム本来のブロックでも使えます(たとえばかまどの facing と lit)。

デフォルトから外れたステートは、見た目を変えられます。テクスチャを textures/block/<id>_<名前>.png(オンのトグル)または <id>_<名前><n>.png(数値)または <id>_<値>.png(名前)に、またはモデルを models/block/<id>_<名前>.json に置きます。まず組み合わせ全体(<id>_lit_stage2)が試され、次に各ステートが単独で試されます。例の lamp.json と lamp_lit.json は Mod の2つのモデルで、たとえば親に minecraft:block/orientable を使い、前面・側面・上面のテクスチャを指定します。

ステートによる光。 light_when: "lit" を指定すると、ブロックの light はそのトグルがオンの間だけ光ります。ランプのようにです:

content/lamp.craftCraftScript
block "lamp" {
    light: 15
    light_when: "lit"
    states: ["lit"]
    on_use: fun(p, b) { b.set_state("lit", !b.state("lit")); return true }
}

Kotlin では facing()、facingAll()、toggle("lit")、number("stage", 3)、choice("shape", "top", "middle", "bottom")、コード内では block.state(…) と block.setState(…):

content/States.ktKotlin
block("lamp") {
    model = "block/lamp"
    facing()
    toggle("lit")
    number("stage", 3)
}

エフェクト

Mod は独自のステータスエフェクトを追加できます。ゲームのものと同じように画面に表示され、同じ方法で付与・確認できます。

content/frozen.craftCraftScript
effect "frozen" {
    color: "#88CCFF"
    kind: "harmful"
    on_tick: fun(e, level) { e.damage(level) }
}
  • color:パーティクルとアイコンの背景の色。
  • kind:beneficial、harmful、neutral のいずれか。
  • on_tick:fun(e, level)。エンティティがそのエフェクトを持っている間、毎秒実行され、レベル(1 が I)を受け取ります。
  • アイコンは Mod の textures/mob_effect/<id>.png です。

付与は e.add_effect("mymod:frozen", 3, 1)(id、秒数、レベル)、確認は e.has_effect("mymod:frozen") で、ゲームのエフェクトと同じです(ワールドとプレイヤーを参照)。Kotlin では:

content/Frozen.ktKotlin
content.effect("frozen") {
    color = 0x88CCFF
    kind = EffectKind.HARMFUL
    onTick = { e, level -> /* … */ }
}

レッドストーン

content/battery.craftCraftScript
block "battery" {
    texture: "minecraft:block/copper_block"
    redstone: true
    on_use: fun(p, b) { if b.state("power") > 0 { b.set_state("power", 0) } else { b.set_state("power", 15) }; return true }
}

redstone: true にすると、ブロックは power ステート(0~15 の数値で、自動的に追加されます)と同じ強さの信号を出します。b.set_state("power", 15) でオンになり、周囲のワイヤー、ランプ、ドアが反応します。block.redstone_power は周囲から受け取る動力で、それが変化すると on_neighbor_change が実行されます(上のランプがこれを使っています)。

Kotlin では:redstone = true と block.redstonePower。

content/Battery.ktKotlin
block("battery") {
    texture = "minecraft:block/copper_block"
    redstone = true
    // in a handler: ctx.block.redstonePower
}

インベントリ

content/crate.craftCraftScript
block "crate" { texture: "minecraft:block/barrel_side", inventory: 27 }

inventory: 27 は、ブロックにそのスロット数(9~54、1行9個)を与えます。アイテムは再起動後も保持され、使うとチェストの画面が開き(on_use がクリックを処理した場合を除く)、壊すと中身がドロップします。1 から 8 スロットでは画面は開かず、Mod 自身がアイテムを出し入れします。

コードからは block.inventory(ゲームのチェストやバレルでも使えます)で set(slot, item(…))、get(slot)、count(id)、add(…) が使えます。Kotlin では:inventory = 27。

content/Crate.ktKotlin
block("crate") {
    texture = "minecraft:block/barrel_side"
    inventory = 27
}

ブロックに表示されるアイテム。 shows_item: 14 を指定すると、ブロックの最初のスロットにあるアイテムが、ブロックの下端からそのピクセル数の高さで、回転しながら浮かびます。すべてのプレイヤーに見え、スロットが空になるかブロックが壊れると消えます。台座は、プレイヤーの手のアイテムを受け取り、返します:

content/pedestal.craftCraftScript
block "pedestal" {
    shape: [[2, 0, 2, 14, 12, 14]]
    inventory: 1
    shows_item: 14
    on_use: fun(p, b) {
        let inv = b.inventory
        if inv.get(0) == null and p.held_item != null {
            inv.set(0, p.held_item)
            p.set_held_item(null)
        } else if inv.get(0) != null {
            p.give(inv.get(0))
            inv.set(0, null)
        }
        return true
    }
}

player.set_held_item(stack) はプレイヤーのメインハンドにアイテムを入れ、null なら空にします。Kotlin では:showsItem = 14 と player.setHeldItem(stack)。

content/Pedestal.ktKotlin
block("pedestal") {
    box(2, 0, 2, 14, 12, 14)
    inventory = 1
    showsItem = 14
    onUse { ctx ->
        val inv = ctx.block.inventory!!
        val held = ctx.player.heldItem
        val shown = inv[0]
        if (shown == null && held != null) { inv[0] = held; ctx.player.setHeldItem(null) }
        else if (shown != null) { ctx.player.give(shown); inv[0] = null }
        true
    }
}

テクスチャ

テクスチャは Mod の中に入れて配布するので、誰もリソースパックをインストールする必要はありません。ファイル名が id になります。

Mod 場所
CraftScript(フォルダー) mods/rubies/textures/item/ruby.png、mods/rubies/textures/block/ruby_ore.png
Kotlin または Java src/main/resources/assets/rubies/textures/item/ruby.png

Mod が同じフォルダーに独自のモデル、レシピ、ルートテーブルを入れている場合、Crafting はそれを使います。

Kotlin では

content/Blocks.ktKotlin
package com.example.rubies.content

object Blocks {
    fun register(content: ContentBuilder) {
        content.block("ruby_ore") {
            hardness = 3f
            requiresTool = ToolType.PICKAXE
            minTier = ToolTier.IRON
            drop("ruby", 1..2)
            drop("minecraft:diamond", chance = 0.1)
        }
        content.block("ruby_block") { hardness = 5f; luminance = 7; sound = SoundGroup.METAL }
    }
}

id。名前空間がない id は、あなたの Mod のものになります("ruby" は rubies:ruby)。ゲームのコンテンツには名前空間を書きます:"minecraft:diamond"。minecraft 名前空間にコンテンツを登録することはできません。