GameTestを使ってスクリプトを動かそう #1

 忘れないうちに書いておこうかなと思いました。

◆GameTestとは?

 詳しくは忘れたけど、v1.17のベータぐらいで追加された超ニッチコンテンツです。今はある程度の要素が正式リリースバージョンで使えるはずです。

 もともとは、JavaScriptというホントのプログラミング(言語)を使ってプログラムを作り、専用のストラクチャセットを使ってワールド内でアドオンのコンテンツを検証するみたいなものです。

 アドオンの検証なんて普通にできるので正直いらないと思いますが、どこかの誰かさん(複数)があることに気づくわけです。


本当にGameTestのテストを実行をしないとJavaScriptは動かないのか??


 なんということでしょう、テストを実行していなくともJavaScriptが読み込まれるではありませんか(そんなに驚くことでもないけど)。

 簡単な原理の説明とかは書くのをやめました。どうせ長文になるので。

◆manifest.json に違いアリ

 実は、JavaScriptを特別に使うので、普通のビヘイビア用からいくつか編集する必要があります。


{

 "format_version": 2,

 "header": {

  "description": "",

  "name": "My Script",

  "uuid": "21a27fbb-5d59-4673-8564-eef265e3cf53",

  "version": [ 0, 0, 1 ],

  "min_engine_version": [ 1, 16, 220 ]

 },

 "modules": [

  {

   "description": "",

   "type": "javascript",

   "uuid": "7006ca3a-0b2b-493e-8ac2-e7ea1a24633d",

   "version": [0, 1, 0],

   "entry": "scripts/my_script.js"

  }

 ],

 "dependencies": [

  {

   "uuid": "6f4b6893-1bb6-42fd-b458-7fa3d0c89616",

   "version": [0, 1, 0]

  },

  {

   "uuid": "b26a4d4c-afdf-4690-88f8-931846312678",

   "version": [0, 1, 0]

  }

 ]

}


いつもと違うところは3か所あります。

1. modules の type

 13行目のtypeは「"data"」じゃなくて「"javascript"」にしてください。

2. modules の entry

 16行目のentryに今回動かすスクリプトのファイルを指定します。manifest.jsonと同じ階層に「scripts」フォルダを作ってその中に「my_script.js」というファイルを入れているならば、上のように「"scripts/my_script.js"」と指定します。

3.dependencies

 19行目以降ではdependenciesで二つのものを指定します。バージョンもuuidも上記のお手本と完全に一致させてください。


 それ以外はいままでと変わりません。自由に指定してください。

!注意!

 上記のお手本は見やすさのため、インデントに全角スペースを使っています。全部コピーする場合は気を付けてください。全角スペース×1を半角スペース×2に変えるなどしないと使えません。

◆スクリプトを書く!

 まずはHelloWorldからですかね。


import { Commands, World } from "mojang-minecraft";

Commands.run("say HelloWorld!", World.getDimension("overworld"));


 コマンド実行がイチバンやりたくなると思ったのでコマンドでチャットに「HelloWorld!」を出力します。実はScriptingAPIより簡単だったり。

 しかし、先に言っておきます。原理的には何も問題ないんですが、このスクリプトを使ってワールドに入ってもチャット欄に「HelloWorld!」は出てきません。なぜかというと、ワールドが生成される前に実行されてしまうからです。

 動くコードはあとでちゃんと作るので、先に解説するところを解説させてください。

1. import文

 JavaScriptはマイクラのものではないので、当然マイクラのことはなんもわからんし、なんもできないです。

 そこで、一行目にああやって書くことでマイクラのデータを取ってこられるようにマイクラの中のものを操れるようにしてあげます。

 しかし、一度に全部というと使わない機能とかは無駄になるので必要なものだけをとってきます。そして今回必要な機能が{・}の中身にある「Commands」クラスと「World」クラスです。

2. 実行

 2行目では早速Commandsクラスの機能を使います。2行目の頭は「Commands」になっていますよね。

 クラスの中にはマイクラから取得したデータ(プロパティ)マイクラのなかでできる機能(メソッド)が入っています。道具箱(=クラス)の中にネジやボルト(=プロパティ)とドライバーやレンチ(=メソッド)が入っているイメージですかね?

 今回はCommandsクラスから「コマンドを動かす」という機能を使います。クラスから何かを引き出すときにはドット( . )に続けてプロパティ名またはメソッド名を書きます。そして、肝心の「コマンドを動かす」という機能は「run」メソッドです。

 メソッドは関数みたいなものなので、すぐ後ろにカッコがつきます。カッコの中には機能を使うために必要な引数を書きならべます。

 コマンドを動かすためには、そもそもコマンドの内容が必要ですよね? 一つ目の引数にはコマンドの内容を、二つ目にディメンションが必要らしいです。

 ディメンションですが、とある特殊な型でじゃないといけないらしいので、Worldクラスの機能、つまりgetDimensionメソッドで変換したものをそのままぶち込みます。鉄分が足りない!と言って鉄の塊をガブガブするひとはいない、みたいな感じですかね。

 一通りかみ砕いて解説しました。もっと掘り下げるともっと長くなるのでとりあえずこんな感じといったところ。

 では、HelloWorld!が出力されるように改良しましょう!


import { Commands, World } from "mojang-minecraft";

let currentTick = 0;

World.events.tick.subscribe(eventData => {

  if(currentTick < 300){

    currentTick += 1;

  }

  if(currentTick == 200){

    Commands.run("say HelloWorld!", World.getDimension("overworld")); 

  }

});


 だんだんとJavaScriptの知識が必要になっていきますね。letとか+=とかifはわかるものとします。アロー関数( => )の知識はあんまりいらないです。

 今回もっとも説明すべきなのは「World.events.tick.subscribe」ですね。Worldをimportして使い、World.events.tick.subscribe(eventData => { //処理 }); で一つのカタマリだと考えればいいと思います。

 そしてこれは、カッコの中に書いた処理が毎tick実行されます。当然そこに先ほどのコマンドを動かす処理を一本だけ書けば1tickごとに「HelloWorld! HelloWorld! HelloWorld! HelloWorld!...」と送られてきます。

 今回わざわざifを使って何かやっているのは、ワールドに入って少ししたら一回だけ「HelloWorld!」と送られるように調整しています

 if構文がわかっているものだとするので簡単に説明すると、毎tick「CurrentTick」が1増えていき、それが200になったら/sayコマンドを実行するという流れです。その後、裏でCurrentTickの数値が無限に増えていくのが嫌だったので300で止まるようになっています。


 以上のスクリプトは両方ともv1.18.22βで動作確認しました。バージョンによってクラス名などの変更が多いので適宜この記事を修正していきたいと思っていますが、あんまり正確に追える自信はりません。


 今回はここまで。ネタができたら#2を書こうかなと思います!

MinecraftBEアドオン-ヒント倉庫

MimecraftBEのアドオン作りで困ったときにここで解決できるようにと個人によって作られたものです

0コメント

  • 1000 / 1000