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: "메모", default: "" } r.text("note")
토글 { toggle: "gift", label: "선물입니다", default: false } r.toggle("gift")
슬라이더 { slider: "amount", label: "수량", min: 1, max: 64, step: 1, default: 8 } r.number("amount")
선택 { choice: "color", label: "색상", options: ["red", "blue"], default: "red" } r.choice("color")
  • 각 필드 키에는 영문 소문자, 숫자, _를 씁니다. label은 플레이어에게 보이는 텍스트이며, 없으면 키가 사용됩니다.
  • buttons는 { id, label } 또는 id만으로 된 목록입니다. 버튼이 없는 양식에는 “확인” 버튼이 붙습니다.
  • 응답에서 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의 기존 바를 반환합니다. 바 하나에 id 하나이므로 모드를 다시 불러와도 중복되지 않습니다.
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().

모드의 키

모드는 자체 키를 추가할 수 있습니다. key로 선언하고 on key로 반응하며, on key는 키를 누른 플레이어에 대해 서버에서 실행됩니다. e.key는 모드의 네임스페이스가 붙은 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) }
}

키는 옵션 > 조작 > 키 설정에 모드 이름의 섹션으로 표시됩니다. 플레이어가 바꿀 수 있고 선택은 저장됩니다. 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 클라이언트에서 보입니다. 서버 모드는 누구도 아무것도 설치하지 않아도 이를 사용할 수 있습니다.
  • 제목, 액션 바, 채팅 메시지는 월드와 플레이어에서 다룹니다.
  • 직접 배치를 정하는 사용자 정의 화면(메뉴, 기계 인벤토리)은 아직 없습니다. 로드맵을 참고하세요.