4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Minecraft BEでJavaScriptを使用したアドオンを作る備忘録

Last updated at Posted at 2023-10-21

はじめに

BEのアドオン開発を書いたjavascript周りの記事がなかなか見つかりづらかった&ドキュメント見ても書いてないものがあったので備忘録として記載

Minecraft Bedrock Edition 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

manifest.json

これが無いとまず認識してくれない
先程作ったsampleフォルダ内にmanifest.jsonを作成

com.mojans
 ┗development_behavior_packs
  ┗sample
   ┗manifest.json

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"
        }
    ]
}

読み込まれた際にnameとdescriptionがそれぞれこんな感じになる
image.png

2箇所のuuidはそれぞれUUIDジェネレーターで取ってきた値を入れる
私は面倒なのでVSCodeのUUID Generatorという拡張機能で入れてます

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

type

scriptを指定 modules内で複数書く時にdataなら問題ないがものによっては競合するみたいな記載をどこかで見た 今回はmodules内が1個だけなので気にしない

entry

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内にプログラムを書く

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)

system.runInterval(func,tickInterval)

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

world.getAllPlayers()

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

player.location

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

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

player.dimension.id

minecraft:overworldやらminecraft:netherやらminecraft:the_endを返してくる
どのディメンション+座標のセットにしないとネザー行ってもオーバーワールド側変更しちゃってあれ?みたいになる

world.getDimension(dimension).runCommand(command)

dimensionのワールドでコマンド実行する
クリエイティブをあまりやらないのでわからないがそういうコマンドとか使える 実行者はサーバーなので近い人みたいな相対的になるオプションは使えない・・・と思う(試してない)

おまけ備忘録

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

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

【world】の【afterEvent/beforeEvent】の【afterEvent/beforeEventを抜いてキャメルケースにしたクラス名】をsubscribeする

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

なんじゃそりゃって感じではあるがイベントリスナー登録はこれで解決した

4
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?