API

インターフェース

プレイヤーが入力するフォームと、画面上の要素(ボスバーとサイドバー)。どれも、Crafting をインストールしているかどうかに関係なく、どのクライアントでも動きます。

フォーム

フォームにはタイトル、本文、フィールド、ボタンがあります。ui/ のファイルで宣言し、必要な場所(コマンド、イベント、アイテムの使用時)で表示します。

ui/shop.craftCraftScript
import { give_rubies } from "/lib/rewards"

const SHOP = form("Ruby shop", {
    body: "Rubies cost 10 emeralds each.",
    fields: [
        { slider: "amount", label: "Rubies", min: 1, max: 16, default: 1 },
        { toggle: "gift", label: "Wrap as a gift" },
        { choice: "pouch", label: "Pouch", options: ["leather", "silk"] },
        { text: "note", label: "Note" }
    ],
    buttons: [{ id: "buy", label: "Buy" }, "cancel"]
})

fun open_shop(p: Player) {
    p.show_form(SHOP, fun(r) {
        if r.button != "buy" { return }                  // closed with Esc or cancelled
        let n = int(r.number("amount") ?? 1)
        if p.inventory.count("minecraft:emerald") < n * 10 { p.send("&cNot enough emeralds"); return }
        give_rubies(p, n)
        if r.toggle("gift") { p.send("&dWrapped in {r.choice("pouch")}: {r.text("note")}") }
    })
}
commands/shop.craftCraftScript
import { open_shop } from "/ui/shop"

command shop describe "Buy rubies" {
    if player == null { return "Players only" }
    open_shop(player)
}
フィールド 書き方 読み取り方
テキスト { text: "note", label: "Note", default: "" } r.text("note")
トグル { toggle: "gift", label: "It's a gift", default: false } r.toggle("gift")
スライダー { slider: "amount", label: "Amount", min: 1, max: 64, step: 1, default: 8 } r.number("amount")
選択肢 { choice: "color", label: "Color", options: ["red", "blue"], default: "red" } r.choice("color")
  • 各フィールドのキーには小文字、数字、_ を使います。label はプレイヤーに見える文字列で、ない場合はキーが使われます。
  • buttons は { id, label } または id だけの一覧です。ボタンのないフォームには「OK」ボタンが付きます。
  • 回答では、r.button が押されたボタンの id で、プレイヤーがフォームを閉じた(Esc)場合は null です。r.values はすべてのフィールドを持つマップです。
  • 回答は show_form に渡した関数に届きます。プレイヤーが迷っている間も、サーバーの他の部分は動き続けます。

Kotlin では

ui/ShopForm.ktKotlin
package com.example.rubies.ui

object ShopForm {
    private val form = Form("Ruby shop").apply {
        body = "Rubies cost 10 emeralds each."
        slider("amount", "Rubies", 1.0, 16.0, default = 1.0)
        toggle("gift", "Wrap as a gift")
        choice("pouch", "Pouch", listOf("leather", "silk"))
        text("note", "Note")
        button("buy", "Buy")
        button("cancel", "Cancel")
    }

    fun show(player: Player) = player.showForm(form) { r ->
        if (r.button != "buy") return@showForm                 // closed with Esc or cancelled
        val n = (r.number("amount") ?: 1.0).toInt()
        if (player.inventory.count(Identifier.parse("minecraft:emerald")) < n * 10) { player.send("&cNot enough emeralds"); return@showForm }
        player.give(ItemStack.of(Items.RUBY, n))
        if (r.toggle("gift") == true) player.send("&dWrapped in ${r.choice("pouch")}: ${r.text("note")}")
    }
}

Form(title) に body、text(key, label, default, maxLength)、toggle(key, label, default)、slider(key, label, min, max, step, default)、choice(key, label, options, default)、button(id, label)。player.showForm(form) { r -> … } は、button、values と text、toggle、number、choice を持つ FormResponse を受け取ります。

ボスバー

画面上部のバーで、タイトル、色、進行度、スタイルを持ちます。タイマー、サーバーのイベント、何かの体力などに使います。

events/countdown.craftCraftScript
const TIMER = server.boss_bar("rubies:countdown", "&cルビーラッシュ", "red", "segments_10")
let left = 60

on join { TIMER.show(player) }

every 1 second {
    left = max(0, left - 1)
    TIMER.progress = left / 60
    TIMER.title = "&cルビーラッシュ:残り {left} 秒"
    if left == 0 { TIMER.remove() }
}
メンバー 内容
server.boss_bar(id, title?, color?, style?) バーを作成するか、その id の既存のバーを返します。1 本のバーに 1 つの id。Mod を再読み込みしても重複しません。
bar.progress 0 から 1。
bar.title テキスト。& の色が使えます。
bar.color pink、blue、red、green、yellow、purple、white。
bar.style solid、segments_6、segments_10、segments_12、segments_20。
bar.show(player)、bar.hide(player) 誰に見えるか。bar.players で一覧が取れます。
bar.remove() 全員から消し、id を解放します。

Kotlin では Crafting.server?.bossBar("rubies:countdown", "Time", BarColor.RED, BarStyle.SEGMENTS_10)。プロパティは同じで、camelCase になります。

サイドバー

画面右側に表示される最大 15 行の一覧で、プレイヤーごとに異なります。もう一度呼ぶと更新されます。

events/welcome.craftCraftScript
import { visits } from "/lib/storage"

on join {
    player.set_sidebar("&6ルビー", [
        "&f訪問回数:&e{visits(player)}",
        "&fルビー:&c{player.inventory.count("rubies:ruby")}"
    ])
}
  • player.set_sidebar(title, lines) で表示または更新します。見えるのはそのプレイヤーだけです。色は & で。
  • player.clear_sidebar() で消します。
  • Kotlin では player.setSidebar(title, lines) と player.clearSidebar()。

Mod のキー

Mod は独自のキーを追加できます。key で宣言し、on key で反応します。on key は、押したプレイヤーについてサーバー上で実行されます。e.key は Mod の名前空間付きの id です(dashmod:dash)。

content/keys.craftCraftScript
key "dash" { label: "Dash", default: "R" }
key "heal" { label: "Second wind", default: "G" }

on key(e) {
    let p = e.player
    if e.key == "dashmod:dash" && !p.has_cooldown("minecraft:feather") {
        let d = p.direction
        p.velocity = vector(d.x * 1.6, 0.35, d.z * 1.6)
        p.set_cooldown("minecraft:feather", 2)
    }
    if e.key == "dashmod:heal" { p.heal(6) }
}

キーは「オプション > 操作設定 > キー割り当て」に、Mod の名前のセクションとして表示されます。プレイヤーは変更でき、その選択は保存されます。default は "R"、"G"、"F6"、"LEFT_ALT" のようなキー名です。

キーを使うには、プレイヤーのゲームに Crafting がインストールされている必要があります。Kotlin では ContentBuilder.key("dash", label = "Dash", default = "R") と Crafting.events.on<PlayerKeyEvent> { e -> … } です。

知っておくと良いこと

  • フォーム、バー、サイドバーは、Crafting の有無に関係なく、どの Minecraft Java 26.3 のクライアントにも表示されます。サーバーの Mod なら、誰も何もインストールせずに使えます。
  • タイトル、アクションバー、チャットメッセージについては ワールドとプレイヤーで扱っています。
  • 独自レイアウトのカスタム画面(メニュー、機械のインベントリ)はまだありません。ロードマップを参照してください。