Skip to content

玩法示例

以下示例演示如何通过 API 实现常见玩法。LittleKt 语法细节见 语言文档

玩家玩法

欢迎提示

绑定到 ClientLoadAddonsFinishServerEvent

kotlin
val playerId = event["playerId"]
clientSys.createMsgbox(playerId, "欢迎来到服务器!")
println("玩家 $playerId 加入了游戏")

死亡统计

绑定到 PlayerDieEvent

kotlin
val playerId = event["playerId"]

// 初始化统计
if (db["death_count"] == null) {
    db["death_count"] = [:]
}

// 累加
val old = db["death_count"][playerId] ?: 0
db["death_count"][playerId] = old + 1

println("$playerId 死亡了 ${db["death_count"][playerId]} 次")

饥饿值控制

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreatePlayer(playerId)

// 设为满饱食度
comp.SetPlayerHunger(20)

// 关闭饥饿掉血
comp.SetPlayerNaturalStarve(false)

println("玩家 $playerId 饱食度已恢复")

禁止/允许飞行

kotlin
val playerId = event["playerId"]
val flyComp = serverApi.GetEngineCompFactory().CreateFly(playerId)

// 给予飞行能力
flyComp.ChangePlayerFlyState(true)

// 检查飞行状态
if (flyComp.IsPlayerFlying()) {
    println("玩家正在飞行")
}

禁止移动和跳跃

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreatePlayer(playerId)

// 冻结玩家
comp.SetPlayerMovable(false)
comp.SetPlayerJumpable(false)
clientSys.createMsgbox(playerId, "你被冻结了!")

传送玩家到其他维度

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateDimension(playerId)

// 传送到末地 (0, 64, 0)
comp.ChangePlayerDimension(2, (0, 64, 0))

设置玩家称号

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateName(playerId)

comp.SetPlayerPrefixAndSuffixName(
    "红队", serverApi.GenerateColor("RED"),
    "战士", serverApi.GenerateColor("GOLD"),
    serverApi.GenerateColor("BLUE")
)

控制快捷栏

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreatePlayer(playerId)

// 切到第 3 格
comp.ChangeSelectSlot(2)

设置拾取范围

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreatePlayer(playerId)

// X 轴 ±5,Z 轴 ±3,Y 轴不变
comp.SetPickUpArea((5, 0, 3))
clientSys.createMsgbox(playerId, "拾取范围已扩大!")

获取在线玩家列表

kotlin
val players = serverApi.GetPlayerList()
println("当前在线:${players.size} 人")
for (playerId in players) {
    println("- $playerId")
}

实体玩法

生成生物

kotlin
// 在主世界 (0, 65, 0) 生成一只僵尸
serverSys.i.CreateEngineEntityByTypeStr("minecraft:zombie", (0, 65, 0), (0, 0), 0)

生成经验球

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateExp(playerId)

// 在玩家位置生成 50 点经验球
comp.CreateExperienceOrb(50, (0, 64, 0), false)

添加/移除状态效果

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateEffect(playerId)

// 力量 II,持续 200 刻(10 秒),显示粒子
comp.AddEffect(serverApi.GetMinecraftEnum().EffectType.STRENGTH, 200, 1, true)

// 速度 III,持续 100 刻(5 秒)
comp.AddEffect(serverApi.GetMinecraftEnum().EffectType.SPEED, 100, 2, true)

销毁实体

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
comp.KillEntity(targetEntityId)
println("已移除实体:$targetEntityId")

检查实体是否存活

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
if (comp.IsEntityAlive(entityId)) {
    println("实体 $entityId 还活着")
} else {
    println("实体 $entityId 已死亡")
}

发射弹射物

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateProjectile(serverSys.levelId)

val param = [
    "position" to (0, 65, 0),
    "direction" to (1, 1, 1)
]
comp.CreateProjectileEntity(playerId, "minecraft:snowball", param)

模拟怪物掉落

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateActorLoot(playerId)

// 模拟守卫者掉落
comp.SpawnLootTable((0, 64, 0), "minecraft:guardian")

世界玩法

设置时间

kotlin
val comp = serverApi.GetEngineCompFactory().CreateTime(serverSys.levelId)

// 正午
comp.SetTimeOfDay(6000)

// 日出
// comp.SetTimeOfDay(0)

// 夜晚
// comp.SetTimeOfDay(13000)

查看当前时间

kotlin
val comp = serverApi.GetEngineCompFactory().CreateTime(serverSys.levelId)
val passedTime = comp.GetTime()
val day = passedTime / 24000
val timeOfDay = passedTime % 24000
println("第 $day 天,游戏刻:$timeOfDay")

设置天气

kotlin
val comp = serverApi.GetEngineCompFactory().CreateWeather(serverSys.levelId)

// 下雨
comp.SetRaining(0.8, 600)

// 雷暴
comp.SetThunder(1.0, 300)

// 检查是否在下雨
if (comp.IsRaining()) {
    println("正在下雨")
}

通知消息

kotlin
val playerId = event["playerId"]

// 单个玩家聊天栏消息
val msgComp = serverApi.GetEngineCompFactory().CreateMsg(playerId)
msgComp.NotifyOneMessage(playerId, "只有你能看到这条消息", "")

// 全服提示
val gameComp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
gameComp.SetNotifyMsg("全服通知", serverApi.GenerateColor("GREEN"))

// 物品栏上方 tip
gameComp.SetOneTipMessage(playerId, serverApi.GenerateColor("YELLOW") + "快捷提示")

// Popup 通知
gameComp.SetOnePopupNotice(playerId, serverApi.GenerateColor("RED") + "警告", "操作不可撤销")

执行原版命令

kotlin
val comp = serverApi.GetEngineCompFactory().CreateCommand(serverSys.levelId)

comp.SetCommand("/time set day")
comp.SetCommand("/weather clear")
comp.SetCommand("/tp @p 0 64 0")

放置/获取方块

kotlin
val comp = serverApi.GetEngineCompFactory().CreateBlockInfo(serverSys.levelId)

// 获取方块
val block = comp.GetBlockNew((0, 64, 0), 0)
if (block != null) {
    println("坐标 (0,64,0) 处的方块:${block["name"]}")
}

// 放置橙色羊毛
val stateComp = serverApi.GetEngineCompFactory().CreateBlockState(serverSys.levelId)
val aux = stateComp.GetBlockAuxValueFromStates("minecraft:wool", ["color" to "orange"])
comp.SetBlockNew((0, 65, 0), ["name" to "minecraft:wool", "aux" to aux], 0, 0, true)

放置水

kotlin
val comp = serverApi.GetEngineCompFactory().CreateBlockInfo(serverSys.levelId)
comp.SetLiquidBlock((0, 64, 0), ["name" to "minecraft:water", "aux" to 0], 0)

方块掉落

kotlin
val comp = serverApi.GetEngineCompFactory().CreateBlockInfo(serverSys.levelId)

// 模拟金矿掉落
comp.SpawnResources("minecraft:gold_ore", (0, 64, 0), 0, 1.0, 10)

// 模拟精准采集掉落
comp.SpawnResourcesSilkTouched("minecraft:gold_ore", (0, 64, 0), 0)

物品玩法

给玩家物品

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateItem(playerId)

// 生成一把附魔钻石剑到背包
val sharpness = serverApi.GetMinecraftEnum().EnchantType.Sharpness
val itemDict = [
    "itemName" to "minecraft:diamond_sword",
    "count" to 1,
    "auxValue" to 0,
    "enchantData" to listOf(sharpness to 5),
    "customTips" to "§b传说之剑§r"
]
comp.SpawnItemToPlayerInv(itemDict, playerId, 0)

println("已赠送传说之剑!")

获取玩家当前手持物品

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateItem(playerId)

val carriedItem = comp.GetPlayerItem(serverApi.GetMinecraftEnum().ItemPosType.CARRIED, 0)
if (carriedItem != null) {
    println("手持:${carriedItem["itemName"]} x${carriedItem["count"]}")
} else {
    println("手上没有物品")
}

附魔物品

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateItem(playerId)

// 槽位 0 的物品添加 锋利 5
comp.AddEnchantToInvItem(0, serverApi.GetMinecraftEnum().EnchantType.Sharpness, 5)

修改背包物品数量

kotlin
val playerId = event["playerId"]
val comp = serverApi.GetEngineCompFactory().CreateItem(playerId)

// 将槽位 0 的物品设为 64 个
comp.SetInvItemNum(0, 64)

读写容器(箱子等)里的物品

kotlin
val comp = serverApi.GetEngineCompFactory().CreateItem(serverSys.levelId)

// 读取 (100, 64, 100) 处容器、槽位 0、主世界
val item = comp.GetContainerItem((100, 64, 100), 0, 0, true)
if (item != null) {
    println("容器里有:${item["newItemName"]} x${item["count"]}")
}

// 放入一个钻石
val diamond = [
    "itemName" to "minecraft:diamond",
    "count" to 64,
    "auxValue" to 0
]
comp.SetContainerItem((100, 64, 100), 0, 0, diamond)

游戏规则

保护区(禁止破坏的区域)

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
// x:-20~20, y:0~255, z:-20~20 的区域不可破坏
val fieldId = comp.AddBlockProtectField(0, (-20, 0, -20), (20, 255, 20))
if (fieldId > 0) {
    println("保护区设置成功,ID:$fieldId")
}

禁止液体流动

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
comp.ForbidLiquidFlow(true)
println("液体流动已禁止")

禁用特定物品

kotlin
val comp = serverApi.GetEngineCompFactory().CreateItemBanned(serverSys.levelId)
comp.AddBannedItem("minecraft:tnt")
comp.AddBannedItem("minecraft:lava_bucket")
println("已禁用 TNT 和岩浆桶")

设置重力

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
comp.SetLevelGravity(-0.04)  // 月球重力
println("重力已切换为月球模式")

禁止掉落/饥饿

kotlin
val comp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
comp.SetDisableDropItem(true)   // 禁止丢物品
comp.SetDisableHunger(true)     // 禁止饥饿

Tick 定时任务

绑定到 OnMCTick,用计数器降频。

每 30 秒广播一次

kotlin
// ⚠️ 按 20tick/秒 估算,600 刻 ≈ 30 秒
var tick = globals["tick"]
if (tick == null) {
    globals["tick"] = 0
    tick = 0
}
globals["tick"] = tick + 1

if (tick % 600 == 0) {
    val gameComp = serverApi.GetEngineCompFactory().CreateGame(serverSys.levelId)
    gameComp.SetNotifyMsg("服务器第 ${tick / 20} 秒运行中...", serverApi.GenerateColor("GRAY"))
}

每 5 分钟清理一次掉落物

kotlin
var tick = globals["clean_tick"]
if (tick == null) {
    globals["clean_tick"] = 0
    tick = 0
}
globals["clean_tick"] = tick + 1

// 6000 刻 ≈ 5 分钟
if (tick % 6000 == 0) {
    val comp = serverApi.GetEngineCompFactory().CreateCommand(serverSys.levelId)
    comp.SetCommand("/kill @e[type=item]")
    println("已清理掉落物")
}

综合玩法

领地保护 + 破坏拦截

绑定到 ServerPlayerTryDestroyBlockEvent

kotlin
val playerId = event["playerId"]
val x = event["x"]
val y = event["y"]
val z = event["z"]

// 示例保护区:x:0~50, z:0~50 为中心城
if (x >= 0 && x <= 50 && z >= 0 && z <= 50) {
    event["cancel"] = true
    clientSys.createMsgbox(playerId, "这是主城保护区,禁止破坏!")
    clientSys.vibrateDevice(playerId, 200)
}

聊天关键词 + 弹窗回复

绑定到 ServerChatEvent

kotlin
val msg = event["message"]
val playerId = event["playerId"]

when {
    msg.contains("菜单") -> {
        clientSys.createMsgbox(playerId, "========\n1.传送大厅\n2.商店\n3.排行榜\n========")
    }
    msg.contains("规则") -> {
        clientSys.createMsgbox(playerId, "服务器规则:\n1.禁止作弊\n2.友好交流\n3.禁止破坏他人建筑")
    }
    msg.contains("tpa") -> {
        // 传送请求 - 用确认框
        clientSys.createConfirmbox(playerId, "确定要请求传送吗?", fun(ok) {
            if (ok) {
                println("$playerId 请求了传送")
            }
        })
    }
    else -> {}
}

死亡惩罚

绑定到 PlayerDieEvent

kotlin
val playerId = event["playerId"]

// 死亡后弹出提示
clientSys.createMsgbox(playerId, "你死了!死亡不掉落已开启,请继续冒险。")
clientSys.vibrateDevice(playerId, 1000)

// 扣除经验
val comp = serverApi.GetEngineCompFactory().CreateExp(playerId)
val total = comp.GetPlayerTotalExp()
val lost = total / 2
comp.SetPlayerTotalExp(total - lost)
println("$playerId 死亡损失了 $lost 经验")

宝箱奖励

绑定到 ContainerItemChangedServerEvent

kotlin
val playerId = event["playerId"]
val pos = event["pos"]

// 检测特定位置的箱子被放入特定物品
val comp = serverApi.GetEngineCompFactory().CreateItem(serverSys.levelId)
val item = comp.GetContainerItem(pos, 0, 0, true)

if (item != null && item["newItemName"] == "minecraft:diamond") {
    // 给玩家额外奖励
    val reward = [
        "itemName" to "minecraft:emerald",
        "count" to 10,
        "auxValue" to 0
    ]
    val playerComp = serverApi.GetEngineCompFactory().CreateItem(playerId)
    playerComp.SpawnItemToPlayerInv(reward, playerId, 0)
    clientSys.createMsgbox(playerId, "你找到了隐藏奖励:10 个绿宝石!")
}

输入兑换码

kotlin
val playerId = event["playerId"]

clientSys.createInputbox(playerId, "请输入礼包兑换码:", fun(code) {
    when {
        code == "VIP2024" -> {
            val comp = serverApi.GetEngineCompFactory().CreateItem(playerId)
            val gift = [
                "itemName" to "minecraft:diamond",
                "count" to 64,
                "auxValue" to 0
            ]
            comp.SpawnItemToPlayerInv(gift, playerId, 0)
            clientSys.createMsgbox(playerId, "VIP 礼包已发放!")
            clientSys.vibrateDevice(playerId, 500)
        }
        code == "" -> {
            // 玩家没输入
        }
        else -> {
            clientSys.createMsgbox(playerId, "无效的兑换码")
        }
    }
})

跨脚本共享数据

利用 globals 在不同脚本间共享状态:

kotlin
// 脚本 A(PlayerDieEvent):记录死亡
val playerId = event["playerId"]
if (db["deaths"] == null) { db["deaths"] = [:] }
db["deaths"][playerId] = (db["deaths"][playerId] ?: 0) + 1

// 脚本 B(ServerChatEvent):查询死亡次数
val msg = event["message"]
val playerId = event["playerId"]
if (msg == "!deaths") {
    val count = db["deaths"][playerId] ?: 0
    clientSys.createMsgbox(playerId, "你共死亡了 $count 次")
}