【統合版アドオン】part-1│究極の機能、ScriptAPIを徹底解説!

スポンサーリンク

初めに

どうも餅わらびすとです。この記事では究極の機能、ScriptAPI(gametestとも言う)を解説します。

ScriptAPIというのは、JavaScriptという言語を使ってプログラムしていく、マイクラアドオンの機能です。
複雑な計算をしたり、マイクラ内のイベントのデータを読み取って処理をしたり、functionなどでは出来ないような色々な機能が沢山あり、アドオンの幅を広げてくれます。プラグインのようなことも実現可能!

役に立つ記事になれば嬉しいです。

目次

・manifest.json
・書く前に知っておいた方が良いこと
・ScriptAPIのつくりを理解する
・よく使うやつ
・エラーの見方
・最後に


~個人的おすすめテキストエディタ~


~見る前に最低限必要な知識~

  • JSONの構造、用語
  • 記号の名称
  • マイクラアドオン構造の基本的な知識

↑難しそうに見えるかもしれませんが情報はネットにいくらでも転がっているので頑張って調べてください

manifest.json

まず、ScriptAPIを使う際には、マニフェストを変える必要があります。

こちらがサンプルコードです。

{
    "format_version": 2,
    "header": {
        "name": "ビヘイビアテストBP",
        "description": "ビヘイビアテストBP",
        "min_engine_version": [1,21,10],
        "uuid": "d8229b16-c69a-40f3-baa6-926f96a5ca6c",
        "version": [1,0,0]
    },
    "modules": [
        {
            "type": "data",
            "uuid": "81344285-81fc-44b7-b8da-6f6f61288c4b",
            "version": [1,0,0]
        },
        {
            "type": "script",
            "language": "javascript",
            "uuid": "440ac9d1-d6f8-4eff-a5aa-29ed51b893f5",
            "entry": "scripts/main.js",
            "version": [1,0,0]
        }
    ],
    "dependencies": [
        {
            "module_name": "@minecraft/server",
            "version": "1.14.0"
        }
    ]
}

modules

まずはmodulesの中から見ていきます。

このマニフェストでは、scriptapiを使わないマニフェストと違い、typeがdataではない、typeがscriptの新しいオブジェクトが入っています。
しかし新しいオブジェクトといえども、中のuuidを変える以外はコピペで大丈夫です。

一応ほかの構成を見てみると、

・languageは使うプログラミング言語、
・entryは実行するscriptのファイルのパス
・versionは存在意義がわからん奴

となっています。言語がpythonやらcやらjavaやらに変えられるわけでもない、entryはファイルの名前さえ変えなければそのまま、versionは数字変えてもこれといった意味もありませんのでとにかくコピペです。

dependencies

次に、dependenciesです。

ここでは変数や関数などをまとめたモジュールというものの、種類やバージョンを指定しているオブジェクトが入っています。

主に使うもののmodule_nameは、

・@minecraft/server
・@minecraft/server-ui

の2つがあります。

serverの方では、ワールドに関することができ、uiの方ではフォームというui的なものを作ることができます。

この例では@minecraft/serverで1.14.0というバージョンを使用していますが、バージョンはアプデするごとに変わっていきます。

そして、scriptapiにはbetaバージョンというそのときのテスト段階のバージョンがあります。この記事の最終確認時のマイクラバージョン1.21.30では1.15.0-betaです。こちらは、現段階ではチャットの内容をとれたりエンティティへ右クリックをしたというイベントを検知(イベントのデータを取得)できたり、まだ1.14.0のような安定版ではできないことができます。このbeta機能は、バージョンの名前を

<使用したいベータバージョン>-beta

として、ワールドの実験機能の設定からベータAPIをオンにすることで使用できます。マインクラフトpreviewなどのマイクラ自体のプレビューは必要ありません。

serverもserver-uiも、このページからその時のマイクラのバージョンを選び、そのページの横にあるモジュール一覧から確認してください。

ちなみに、バージョンが増えるということは1.14.0のような安定版は新しいバージョンが出ても使えるわけですが、betaを使用する場合は毎回変える必要があります。

(2.0.0-alphaというバージョンを指定すれば常に最新のベータが適応されるってのもあるみたいです)

書く前に知っておいた方がいいこと

「早速scriptapiのコードを書いていこう!」と言いたい流れですが、一文だけ覚えても文法を覚えなければ応用活用が利きません。

応用が効くようにしたいということで、ScriptAPIに使用されている、JavaScriptという言語の、基礎について覚えましょう。

しかしこれは基礎なので、複雑な処理をしたい時や今回紹介したことのもっと詳しい仕様を知りたいという場合は、サイトyoutube生成aiなんかに聞きましょう。ちなみに、生成aiにはscriptapiはほとんど書けないのでscriptapiとしてではなくjavascriptとしての質問をするのがおすすめです。

コメント

jsでは、コメントは

//このようにスラッシュをコメントにしたいところから2つつけるか、

/* スラッシュとアスタリスクで囲むとできます。 */

/*
このコメントの場合は、
複数行にわたって
書くこともできます
*/

コメントをするとコメントをした範囲がコードとして認識されなくなるため、処理のメモに使えます。

データ型

プログラミングにおいて、データには種類があります。ScriptAPIで主なものを5つ挙げると、

・string(文字列)
・number(数値)
・boolean(真偽値)
・object(オブジェクト)
・undefined

があります。


stringは、“このようにダブルクォーテーションか,シングルクォーテーションで囲むことにより”   表すことができます。

+で2つの文字列を合わせる、といったことも可能です。(例:”あいさつは” + “大事だよ”)


numberは、そのまま、0や100のようにして表せます。

+ – * / % などで計算ができます。右から、意味は加算 減算 乗算 除算 剰余演算となっています。


booleanは、trueとfalseで表すことができます。

そのまんま。[はい、いいえ]のようななものです。


objectは、[]で囲まれたものと{}で囲まれたものがあります。

[]のほうはArray(配列)と言い、複数のデータをコンマで区切って入れることができます。(例:[“一つ目のデータ”, 2, 3])    そして、その中のデータを要素と呼びます。
データは、オブジェクトの名前[番号]で取り出せます。しかし番号は0から始まるので、頭の中ではオブジェクトの名前[番号 – 1]と考えるようにしましょう。

{}のほうは、「プロパティ」というものを用いて、データを保存したり関数(後に説明します)を入れることができます。

//例
{ 
    apple: "red",
    grape: function() {
        world.sendMessage("purple");
    }
}
//こうでもok
{ apple: "red", grape: function() { world.sendMessage("purple"); } }

appleがプロパティの名前で、grapeがメソッド(プロパティに関数を入れたもの)の名前です。

プロパティは、オブジェクト名.プロパティ名で呼び出せ、メソッドはオブジェクト名.メソッド名()で呼び出せます。


undefinedは、値が定義されていないものなどに入ったりする値です。

例えば、定義されていない変数などにはこれがはいっています

定数・変数

この2つは簡単。

//定数の宣言
const 定数の名前 = 入れたいデータ;

//変数の宣言
let 変数の名前 = 入れたいデータ;

こんな感じです。

名前を日本語にするのは非推奨です。これは大抵の命名に当てはまります。初めに数字をつけるのはNGです。これも大抵の命名に当てはまります。

変数は定義した以降に、変数の名前 = 入れたいデータ、とすると再代入できます。

これらをどんなときに使うかというと、

object.red.fruit.apple

こんな感じの、「objectというオブジェクトのredというプロパティのオブジェクトのfruit(以下略)…」のような複雑な値があるとします。
これを毎回このまんま書くのは長ったらしいし面倒です。

これを定数を使うと

const apple = object.red.fruit.apple;

これからはappleと書くだけであの長いコードと同じ意味になります。

関数

関数とは、いくつかの処理を1つにまとめたものです。値を入れたら特定の値が返ってくるものとも言えます。マイクラにもコマンドをまとめたfunctionがありますよね。そんなものです。

関数は、

function 関数の名前(仮引数) {
    処理
}

と書いて定義できます。
呼び出すときは、関数の名前(引数) で出来ます。

まずは関数の名前です。jsの命名規則にのっとっているのならば何でもいいです。

そして処理。
return 値 をつけると、処理の中で出した値などを、関数を呼び出した場所に入れることができます(値が返ってくるとも言う)。そのときに処理が止まるので、returnの値を設定せずにreturnだけで書いて、この条件で処理を止める、のようなこともできます。この場合関数はundefinedを返します。

仮引数と引数は、言葉で説明しづらいですが

//関数を定義
function plus10(number) {
    const n = number + 10;
    return n;
}

//関数の呼び出し
world.sendMessage(plus10(20)); //ワールドに30とチャットされる

こんな関係です。
仮引数はコンマをつけて増やすことができます。引数側もコンマをつけてください。

ちなみに、関数はアロー関数という書き方もあります。こちらは、

const 関数変数名 = (仮引数) => {
    処理
}

で書けます。

if文とかfor文とか

if文は名前からあらかた分かるかもしれませんが条件です。

if (条件) {
    処理
}

if文の中の処理は、()の中にtrueが入ったときに実行されます。
例えば、1 === 1を入れると、1 === 1trueを返す式なので処理が実行されます。

結果は、!をつけると反転できます。trueがfalseになったりfalseがtrueになったり、、、if (!(1 === 1))、if (1 !== 1)

条件は&&でどちらもtrueならという条件にできif (true && true)、||でどちらかがtrueならという条件にできますif (true || false)

for文は反復処理ができます。

for (let i = 0; i <= 実行したい数; i++) {
    処理
}

for (constof 配列) {
    処理
}

上は特に言うことなしです。そのまんま。
下は、配列の要素1つ1つに処理を行います。

クラス・インスタンス

よく言われる例えで、クラスは設計図、インスタンスは設計図に基づいて生成されたオブジェクト。

自分で作るという事は始めのほうはしないと思うので詳しい説明は省略します。使いたくなったときに調べてください。

ScriptAPIの書き方を理解する

コードやっと出てきます。
まず、ビヘイビアのフォルダscriptsというフォルダを作ってください。

作り終えたら、その中にmain.jsというファイルを作ってください。jsonとjsでは違うので、注意してください。ちなみに、jsonは「JavaScript Object Notation」の略だそうです。長い。

そうしたら、中にこう書いてみてください。
末尾に書いてある;はコロンではなくセミコロンなので注意。

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

system.runInterval(function() {
    for (const player of world.getPlayers()) {
        const playerName = player.name;
        player.sendMessage(playerName);
    }
},20);

そして、保存してマイクラで開いてみてください。

どうでしょうか?1秒ごとに自分の名前がチャットに送られていると思います。
それではこのコードの意味を解説していきます。

注意

この解説のクラスのリンクなどは、少し経ったらバージョンが古くなっています。
なので、こちらの公式サイトから常にその時の新しいバージョンのものを確認してください。リファレンスの読み方は変わりません。
ちなみに、個人的に見やすいページとして非公式ですがこのようなものもあります。今回はこちらのリンクを使い解説します。

import { world, system } from “@minecraft/server”;

ここでは、@minecraft/serverモジュールから、Worldクラスのworldというオブジェクト、Systemクラスのsystemというオブジェクトの2つをインポートしています。

system.runInterval(function() {…},20);

ここでは、インポートしたsystemを使用しています。
systemはSystemクラスのオブジェクトなので、Systemクラスのメソッドが使えます。
runIntervalというメソッドを見てみましょう。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-10-222142.png

初めに、Remarksという、その機能の説明を見てみます。
翻訳すると、「インターバルで一連のコードを実行する。」と書いてあるようです。
聞き慣れない言葉はインターバルぐらいですかね。意味は、繰り返し一連のコードを実行する、ということです。

それでは、上から見ていきましょう。初めに、runInterval(callback, tickInterval?): number

とあります。この文から、引数が最大2つ使え、そして2つ目の引数の最後に?がついているため、tickIntervalという引数は、なくても使えることが分かります。

callbackという引数の説明には、callback: (() => void)とあります。ここには関数が入るということです。下の文は、翻訳すると、「このインターバルが発生したときに実行される関数コード。」とあります。

続いて、tickIntervalという引数の説明を見ていきましょう。
こちらには、Optional tickInterval: numberとあります。Optionalからも、tickIntervalがなくとも良いことがわかりました。そして、tickIntervalにはnumberを入れれば良いことも分かりました。
下の文も翻訳して、見てみると「コールバックが呼び出される間隔。」らしいです。名前がtickのintervalなのでtick単位で時間を入れればよさそうです。

そしてReturnを見ると、このメソッドを実行したときに返ってくる値はnumberで、説明によると「この関数の実行をインターバルで停止させるためにclearRunメソッドで使用できる不透明なハンドル。」みたいです。繰り返しをやめるメソッドを使用するのに必要ということです。

つまり、system.runInterval(function() {…},20);は、20ティックごとに{}の中身を実行するという意味だったということ。

for (const player of world.getPlayers()) {…}

ここでは、インポートしたworldを使っています。
worldは、WorldクラスのオブジェクトなのでWorldクラスのメソッドが使えます。
WorldクラスのgetPlayersというメソッドを見てみましょう。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-10-231015.png

今回も初めに、Remarksを見ていきます。
このメソッドは、「フィルタ条件の EntityQueryOptions セットを介して定義された一連の条件に基づくプレーヤーのセットを返します。」らしいです。

それでは、上から見ていきましょう。初めに、
getPlayers(options?): Player[]

とあります。これから、引数にはoptionsというものが入れられるということが分かります。これも?があるため無くとも使えます。

options引数の説明には、options: EntityQueryOptionsとあります。EntityQueryOptionsとは何でしょうか?となって、クリックしてページへ飛んでみると、

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-10-232942.png

色々出てきました。EntityQueryOptionsとはエンティティを取得する際、条件を付けられるインターフェイスのようです。とりあえずはインターフェースはクラスのような概念(設計図)であり、オブジェクトのような実態はないものと考えてください。このページは、まだ下に続いています。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-10-233514.png

1つ例を見てみます。このclosestというプロパティには、numberが入るようです。
Remarksを翻訳すると、「返すエンティティの数を制限し、このプロパティで指定された最も近いN個のエンティティを選ぶ。location 値もクエリオプションオブジェクトで指定する必要があります。」になります。ここでlocationも設定して、比較の中心を決める必要もあるようです。コマンドのセレクターで言うcのようなものみたいですね。

こういうわけで、EntityQueryOptionsを引数に入れた場合のメソッドの例は、以下のようになります。

world.getPlayers({location: {x: 0, y: 0, z: 0}, closest: 1});

話をgetPlayersに戻します。

optionsの次には、Return、つまり返ってくる値が書かれています。
見てみると、どうやらPlayer[]が返ってくるようです。
これは、Playerクラスのオブジェクトが入った配列ということです。

つまりfor (const player of world.getPlayers()) {…}は、playerにgetPlayersで取得した配列の各要素を代入し、{}の中でその個々の要素に処理を行っているという意味だったということです。

forの処理の中

const playerName = player.name;
player.sendMessage(playerName);

恐らくここまで読めたならばなんとなくやってることは分かると思うので、詳しいところは省略します。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-11-001810.png

nameプロパティを見ると、Readonlyと書かれていますね。これは値を再代入できない、ということです。

nameTagとかなら再代入して名前を変えることができます。

そして、sendMessage。これはまんまで、メッセージを送れます。

%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-03-11-002635.png

messageに入れられる値がいろいろごちゃってますが、これはstring,RawMessage,(string,RawMessage)[]のどれでも入れられるという意味です。

つまりこのコードは、プレイヤーの名前を本人にチャットで送るという処理だったといぅことです。

このように、リファレンスを見れば何をどうすればどうなるのかということが分かります。なので、なにか実装したい機能があればまずはリファレンスを見てみましょう。今説明した見方で応用も効くはずなので、リファレンスを見て使えそうな機能で遊んでみてください。分からない処理や単語はその時その時で調べてみましょう。それを繰り返したらその内ScriptAPIのコードが書けるようになっていると思います。

よく使うやつメモ

World
System
Dimension
Entity
ItemStack
Block

↑マイクラの基本になる機能達なので大体はこのクラスの処理

worldのafterEvents、beforeEventsが個人的に強い。イベント系はとにかく色々出来る。

マイクラ内のdevelopment_behavior_packsにアドオンフォルダを入れて、そのアドオン入りワールドで/reloadを実行するとfunctionとscriptapiのファイルが更新されるのでいちいちワールドを変えなくとも良い。

エラーの見方

エラーは、設定にあるクリエイターという欄にあるコンテンツログGUIの有効化をONにすることで見ることができます。
ScriptAPIに限らず、様々な要素のエラーが出てくるのでONにしておいて損は無いです。

エラーは、大抵の場合は翻訳すれば言っていることが分かると思います。

最後に

ここまで読んでいただきありがとうございます!

役に立ったと思ってもらえたら嬉しいです。

なにか質問があるときはこちらのディスコードサーバーから受け付けています。どんな人も大歓迎!一応ここでも受け付けますが内容が複雑になると判断した質問はサーバーでしか受け付けません。

まだScriptAPIについて知らないことも少なくないので、間違っているところがあれば教えてほしいです。

それでは良いアドオンライフを!

>> 次回の記事

※投稿記事に含まれるファイルやリンクにより発生した被害についてクラフターズコロニーは責任を取りません
投稿通報

コメント

  1. 神ですね。ありがとうございます。

    • その言葉が嬉しいです!
      良かったです

  2. scriptAPIのオートコンプリート機能があれば使い方を教えてほしいです。コードエディタはVScodeを使っています。

    • npmをインストールし、https://www.npmjs.com/package/@minecraft/serverこのページからバージョンを選んで、パッケージのインストールのコマンドをコマンドプロンプトにコピペして実行すれば補完が出てくるようになります

  3. scriptapi最高

  4. 自分用メモ

    part-2 世界のイベントを自在にコントロールする
    https://minecraft-mcworld.com/70279/

  5. “dependencies”: [
    {
    “module_name”: “@minecraft/server”,
    “version”: “1.11.0”
    }
    ]
    のversionのbetバージョンの確認(最新アプデごとの)出来るサイト教えてほしいです。

  6. 僕はアドオンを作るときandroidタブレットを使うのですが。
    Minecraftないのファイルをいじれないので/reloadで出来ないんです。
    いちいちインポートしてあーだーこーだするのでアドオン作りがはかどりません。
    androidで利用出来るアプリ(Minecraftは確実)内のファイルをいじれるアプリありませんか?

    • ファイルマネージャーがおすすめです。

      • こんなの?
        %%https://play.google.com/store/apps/details?id=com.alphainventor.filemanager

        url%%

        • 実際に使って確かめてみるのが早いです

  7. 初めのところの
    ScriptAPI(gametestとも言う)というところの網掛けはどうやったんですか?

    • ブログエディタの文字の編集で、1番右のマークを選べば使えます。

      • 左揃えと中央揃えと一つ上に移動と削除と一つ下に移動しかないんですけどどうしたらいいですか?

        • その文字を選択したらペンみたいなマークがいくつか出てくるはずですが…

  8. “dependencies”: [
    {
    “module_name”: “@minecraft/server”,
    “version”: “1.13.0”
    }
    ]
    のversionの安定版のバージョンを確認は

    https://jaylydev.github.io/scriptapi-docs/#script-api-references

    のサイト内にありますか?
    あれば場所を教えて欲しいです。
    見つけきれません…

    • 1.13.0は安定版ですよ。合っています。

      • ありがとうございます!

        そして質問です。
        ===は何何は何何(?)
        &&&は何何と
        たけど(多分(?))
        またはってどう書くんですか?

  9. 質問です。
    ===は何何は何何(?)
    &&&は何何と
    たけど(多分(?))
    またはってどう書くんですか?

コメント通報