API

世界与玩家

读取和修改方块、生成实体、与玩家交互。在 CraftScript 中名称使用 snake_case(block_at、max_health);在 Kotlin 和 Java 中使用 camelCase(blockAt、maxHealth)。它们是同一批对象。

示例

commands/beacon.craftCraftScript
command beacon requires "rubies.beacon" describe "在你所站的位置点亮信标" {
    if player == null { return "仅限玩家使用" }
    let w = player.world
    let at = player.location
    w.set_block(at.block_x, at.block_y, at.block_z, "minecraft:lantern", { hanging: false })
    w.spawn_particle("minecraft:flame", at, 30, 0.5, 0.02)
    w.play_sound(at, "minecraft:block.lantern.place")
    player.title("&e已点亮", "")
}
commands/BeaconCommand.ktKotlin
object BeaconCommand {
    fun register() {
        Crafting.commands.command("beacon") {
            permission = "rubies.beacon"
            executes { c ->
                val at = c.player.location
                val world = c.player.world
                world.setBlock(at.blockX, at.blockY, at.blockZ, Identifier.parse("minecraft:lantern"), mapOf("hanging" to false))
                world.spawnParticle(Identifier.parse("minecraft:flame"), at, count = 30, spread = 0.5, speed = 0.02)
                world.playSound(at, Identifier.parse("minecraft:block.lantern.place"))
                c.player.title("&e已点亮")
            }
        }
    }
}

世界

在 CraftScript 中使用 world()(主世界,或 world("minecraft:the_nether"));在 Kotlin 中使用 Crafting.server?.world(id) 或 player.world。

成员 作用
id, players, time, is_raining, data 世界 id、玩家、游戏时间(可读写)、是否在下雨、存档数据。
block_at(x, y, z) 该位置的方块。
set_block(x, y, z, type) 放置方块。
set_block(x, y, z, type, states) 放置带状态的方块:{ open: true }、{ facing: "north" }。
spawn(type, location) 生成实体。
drop_item(location, stack) 在地上掉落一个物品。
explode(location, power, fire?) 爆炸。
strike_lightning(location) 闪电。
spawn_particle(id, location, count?, spread?, speed?) 粒子。
spawn_particle(id, location, velocity) 按该速度(单位为格每刻)飞行的单个粒子。有些粒子,如 minecraft:enchant 和 minecraft:portal,会飞向它们生成的位置:它们来自 location + velocity。
play_sound(location, id, volume?, pitch?) 在某个位置播放声音。
light_at(x, y, z) 亮度,从 0 到 15。
container_at(x, y, z) 箱子、木桶等的物品栏,或 null。
set_sign_text(x, y, z, lines) 告示牌上的文字。
set_chunk_loaded(cx, cz, loaded) 即使附近没人,也保持区块加载。
entities() 世界中的实体。
living_near(location, radius) 某处附近的生物实体,由近到远。
shoot(projectile, from, velocity, shooter?, damage?) 发射投射物,可以是游戏自带的,也可以是模组的。

玩家

成员 作用
name, uuid, is_op, has_crafting_client 身份信息;客户端是否安装了 Crafting。
send(msg), action_bar(msg), title(title, subtitle?) 聊天栏、动作栏和屏幕上的消息。用 & 表示颜色。
inventory, held_item, give(stack) 物品栏、手持物品、给予物品。
set_held_item(stack) 把物品放入主手,替换原有的东西;null 表示清空。
health, max_health, food_level, game_mode 生命值、饥饿值(可读写)和游戏模式。
is_sleeping 玩家是否在睡觉。
data 随玩家保存的数据(见下文)。
play_sound(id, volume?, pitch?) 只对该玩家播放的声音。
has_permission(p), kick(reason) 权限;踢出。

Player 同时也是活体实体(见下文)。

实体、方块与物品栏

类型 成员
Entity uuid, type, world, location, custom_name, is_alive, data, direction, vehicle;teleport, remove, set_rotation, add_tag, has_tag。
LivingEntity Entity 的全部成员,加上 health, max_health;damage, heal, set_ai, add_effect, remove_effect, has_effect, effects, add_modifier, remove_modifier, attribute, set_attribute, equipment, set_equipment(关闭或开启它自身的行为)。
Block type, x, y, z, world, location, is_solid, data;set_type, relative(dx, dy, dz)。
Inventory size;get(slot), set(slot, stack), add(stack), count(id), clear()。
Location world, x, y, z, yaw, pitch, block_x, block_y, block_z;add(dx, dy, dz), distance_to(other)。

ItemStack 包含 id、数量、名称、描述(lore)以及模组自己的数据,并且在物品栏和箱子之间移动时会保留这些信息。在 CraftScript 中用 item("rubies:ruby", 3) 创建;在 Kotlin 中用 ItemStack.of("rubies:ruby", 3) 或完整的构造函数创建。

stack.enchantments 是从每个附魔的 id 到其等级的映射(minecraft:sharpness → 3);对于附魔书,则是它所给予的附魔。在 Kotlin 中,stack.withEnchantments(mapOf(Identifier.parse("minecraft:sharpness") to 3)) 是带有这些附魔的同一个物品堆。从游戏读取的物品堆,在模组移动它,或用 with_count 或 withEnchantments 修改它时,会保留它拥有的一切,包括 API 没有命名的内容(地图的内容、药水的效果)(Kotlin 的 copy 不会保留)。

效果、属性与装备

**效果。**任何生物实体都可以拥有游戏的效果。e.add_effect("minecraft:speed", 8, 3) 接收 id、秒数和等级(1 即 I);可选的最后一个参数 true 或 false 决定是否显示粒子。配套的还有 remove_effect(id)、has_effect(id) 和 effects(从 id 到 { level, seconds } 的映射)。在 Kotlin 中:addEffect(Identifier.parse("minecraft:speed"), 8.0, 3) 和 ActiveEffect(level, seconds)。

模组可以声明自己的效果(见方块、物品与配方);施加和读取它们用的就是这些成员。

属性。attribute("minecraft:movement_speed") 返回当前值,已计入护甲和效果。set_attribute("minecraft:scale", 1.6) 修改基础值:scale、attack_damage、max_health、jump_strength、armor 等。在 Kotlin 中:attribute(id) 和 setAttribute(id, value)。

commands/grow.craftCraftScript
command grow() {
    let p = player
    if p.attribute("minecraft:scale") > 1.2 { p.set_attribute("minecraft:scale", 1) } else { p.set_attribute("minecraft:scale", 1.6) }
}

**修饰符。**修饰符在不替换基础值的前提下改变属性,所以多个修饰符可以叠加,也可以各自单独移除。e.add_modifier("minecraft:movement_speed", "mymod:frozen_slow", -0.3, "percent_of_base") 接收属性、修饰符的 id、数值和运算方式;e.remove_modifier("minecraft:movement_speed", "mymod:frozen_slow") 将其移除。再次添加相同的 id 会替换它。运算方式有 add(加上该数值)、percent_of_base(加上基础值乘以该数值)和 multiply_total(把结果乘以 1 加该数值)。在 Kotlin 中:addModifier(attr, id, amount, ModifierOperation.PERCENT_OF_BASE)。

commands/chill.craftCraftScript
command chill() {
    player.add_modifier("minecraft:movement_speed", "mymod:chill", -0.3, "percent_of_base")
    // later: player.remove_modifier("minecraft:movement_speed", "mymod:chill")
}

骑乘与范围效果。entity.vehicle 是实体正在骑乘的对象,没有则为 null。world.living_near(location, radius) 按由近到远列出某处周围的生物实体,这正是范围效果所需要的:

commands/frostwave.craftCraftScript
command frostwave() {
    let p = player
    for other in p.world.living_near(p.location, 8) {
        if other.type != "minecraft:player" { other.add_effect("mymod:frozen", 4, 1) }
    }
}

装备。e.equipment("head") 是该栏位上穿戴的物品,没有则为 null;e.set_equipment("main_hand", item("minecraft:iron_sword")) 用来更换。栏位有 main_hand、off_hand、head、chest、legs 和 feet。在 Kotlin 中:EquipmentSlot.HEAD、equipment(slot) 和 setEquipment(slot, stack)。

朝向与冷却。entity.direction 是它注视的方向,长度为一个方块的向量。player.set_cooldown(item, seconds) 和 player.has_cooldown(item) 用来给物品设置冷却并检查。

存档数据

玩家、实体、方块和世界都有 data:一个重启后依然保留的键值存储。它可以存储字符串、数字、布尔值、列表和映射。

lib/storage.craftCraftScript
// Data that survives restarts. Keys start with the mod id: they're shared by every mod.
const VISITS = "rubies.visits"

fun visits(p: Player): number {
    return p.data.get_int(VISITS) ?? 0
}

fun add_visit(p: Player): number {
    let n = visits(p) + 1
    p.data.set(VISITS, n)
    return n
}
storage/Visits.ktKotlin
package com.example.rubies.storage

object Visits {
    private const val KEY = "rubies.visits"   // shared by every mod: prefix it with the mod id

    fun of(player: Player): Int = player.data.getInt(KEY) ?: 0

    fun add(player: Player): Int = (of(player) + 1).also { player.data[KEY] = it }
}
CraftScript Kotlin / Java 作用
data.set(k, v) 或 data[k] = v data[k] = v 存储一个值(null 表示删除)。
data[k] data[k] 按存储时的样子读取一个值,没有则为 null。
data.get_int(k)、get_number、get_string、get_boolean getInt(k)、getNumber、getString、getBoolean 读取该类型的值,不存在则返回 null。
data.remove(k)、data.clear()、data.keys remove(k)、clear()、keys 删除一个键、删除全部、列出所有键。
  • **键由所有模组共享。**每个键都以你的模组 id 开头(rubies.visits),以免覆盖其他模组的键。
  • **保留多久:**玩家的数据跟随玩家;实体的数据在实体死亡时消失;方块的数据在玩家破坏方块或通过 API 替换方块时消失。
  • 数字以小数形式存储;get_int 以整数形式返回。
  • 把键和相关函数放在同一个文件中(lib/storage.craft,Kotlin 中为 storage/):模组的其他部分不需要知道它们。见组织模组。

服务器

成员 作用
players, worlds, motd, tps, is_dedicated 服务器状态;tps 是每秒平均刻数(理想值为 20)。
player(name), world(id) 查找在线玩家或世界。
broadcast(msg) 向所有人发送消息。
stop() 保存并关闭服务器。
run_command(cmd) 兜底手段:执行游戏命令(见下文)。

兜底手段

有两个函数接受游戏自身的格式:run_command(CraftScript 中为 run(…)),用于执行游戏命令;以及 summon(type, location, nbt),用于以游戏内部格式的数据创建实体。它们是为 API 尚未覆盖的场景准备的,但这些格式属于 Minecraft,可能在新版本中改变,所以依赖它们的模组可能会坏。尽量少用,始终优先使用 API。

绝不编造。没有任何 API 成员会返回占位值。如果某件事在当前运行的游戏中无法实现,它会抛出错误,说明是什么以及为什么。