用Minecraft BE创建使用JavaScript的插件的备忘录

首先

由于很难找到关于编写 BE 的 JavaScript 插件开发的文章,并且在阅读文档时发现了一些未记录的信息,所以我将它们记在备忘录里。

Minecraft基岩版1.20.30的Windows版本。

主要目标

我有过使用JavaScript的经验
尽管没有使用过,但我能大概读懂其他编程语言

准备

寻找Minecraft插件所放置的文件夹,它位于AppData文件夹内的一个隐藏文件夹中。具体路径是%localappdata%\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang\。通过按下Win+R并粘贴该路径可轻松找到。

在development_behavior_packs中创建一个新文件夹。尽管这个文件夹的名称不会显示在列表中,但如果创建了大量的插件,为了方便辨认,最好使用一个容易识别的名称。暂且先创建一个名为sample的文件夹。

com.mojans
 ┗development_behavior_packs
  ┗sample

清单文件.json

如果没有这个,他不会首先认出来的。
请在刚才创建的样本文件夹中新建一个manifest.json文件。

com.mojans
 ┗development_behavior_packs
  ┗sample
   ┗manifest.json

写入manifest.json文件的内容

{
    "format_version": 2,
    "header": {
        "name": "TNT",
        "description": "足元がTNTになる",
        "uuid": "【ここにUUID取ってきて入れる】",
        "version": [1,0,0],
        "min_engine_version": [1,16,0]
    },
    "modules": [
        {
            "type": "script",
            "version": [1,0,0],
            "uuid": "【ここにUUID取ってきて入れる】",
            "entry": "scripts/main.js"
        }
    ],
    "dependencies": [
        {
            "module_name": "@minecraft/server",
            "version": "1.5.0"
        }
    ]
}
image.png

2个uuid的值分别取自UUID生成器。
我觉得很麻烦,所以我使用了VSCode的UUID Generator扩展功能来获取这些值。

modulesの書き方について書いてある記事が少なく見つけづらかった部分

请输入

只有一个选项,用中文进行释义:
当在模块内指定脚本时,如果是数据类型的话就没有问题,但据某处的描述,可能会根据不同的对象而发生冲突。由于此次只有一个模块内的脚本,所以不必担心。

入口

在上方提到的地方记录下放置了js文件的位置,尽管目前是scripts/main.js,但是之后会创建一个新的。

创建JavaScript文件

manifest.jsonのentryで記載した通りにscriptsフォルダとmain.jsを作成

com.mojans
 ┗development_behavior_packs
  ┗sample
   ┣manifest.json
   ┗scripts
    ┗main.js

ここまで用意すればゲームで該当のビヘイビアーパックを指定することで読み込みまでしてくれる
チート使用をオンにしておけばjsファイルを更新した際に/reloadで再読込してくれる

请将程序写在main.js文件中。

import { world, system } from "@minecraft/server"

const INTERVAL_SEC = 1 //インターバルで1秒毎に呼ぶ

system.runInterval(() => {
    // 全プレイヤー情報を取得
    const players = world.getAllPlayers()

    // 全プレイヤーに対し処理を実行
    for (const player of players) {

        //playerの座標を取得
        let loc = player.location

        //y座標をプレイヤーの1つ下にセット
        loc.y = loc.y - 1

        // 現在の世界情報を取得 minecraft:overworld or minecraft:nether or minecraft:the_end
        let dimension = player.dimension.id

        // 足元のブロックをTNTに置換
        world.getDimension(dimension).runCommand(`setblock ${loc.x} ${loc.y} ${loc.z} minecraft:tnt`)
    }
}, INTERVAL_SEC * 20)

系统以tickInterval的间隔运行func函数。

https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/system#runinterval
javascriptのsetIntervalと基本的に同じものですが、第二引数の値はミリ秒ではなくminecraftで使用される tick(0.05秒)単位なので秒数にしたい場合は×20する
あんまり頻度が高いとswitchやスマホ勢がカクつく影響あり
windows版でも1秒インターバルでジャンプブリッジして落ちた例あり

世界.获取所有玩家()

https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/world#getplayers
全プレイヤー情報を取得

玩家所在的地点

https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/player#properties
playerクラスのプロパティに書いてないけど座標情報持ってないはずはないと思って取りにいったらあった このあたり公式ドキュメントが優しくない

Entityクラスを拡張してPlayerが作られているのを見落としてました
↓のplayer.dimension.idも同様

player.dimension.id

在Minecraft中,返回Minecraft: Overworld、Minecraft: Nether和Minecraft: The End。如果不设置正确的维度和坐标,前往地狱维度(Nether)后可能会导致变回主世界(Overworld),出现混乱的情况。

在中国本土化为汉语的举例是:世界.获取维度(维度).执行命令(命令)。

在dimension的世界中执行命令
我不怎么玩创造模式,所以不太清楚,但应该可以使用这种命令之类的。执行者是服务器,所以无法使用与接近的人相关的相对选项…我觉得(没试过)。

附赠备忘录

https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/minecraft/server/playerspawnafterevent
PlayerSpawnAfterEventクラスがあってもどう使うかわからなかった
BEアドオン開発のdiscordまで見に行ってやっと理解

HogeFugaBeforeEventクラス/HogeFugaAfterEventクラスがあったらイベント登録方法は

订阅将去掉【世界】的【事件之后/事件之前】的【事件之后/事件之前转为驼峰命名的类名】。

import { world } from "@minecraft/server"
world.afterEvent.hogeFuga.subscribe(event => {
    //処理
})
world.beforeEvent.hogeFuga.subscribe(event => {
    //処理
})

虽然感觉有点奇怪,但通过这个方法解决了事件监听器的注册。

广告
将在 10 秒后关闭
bannerAds