[ScriptAPI参考書] 仕様・情報まとめ #2

# 目次

- [はじめに](#はじめに)
- [モジュールの種類](#モジュールの種類)
    - [@minecraft/server](#minecraftserver)
    - [@minecraft/server-ui](#minecraftserver-ui)
    - [@minecraft/server-gametest](#minecraftserver-gametest)
    - [@minecraft/server-net](#minecraftserver-net)
    - [@minecraft/server-admin](#minecraftserver-admin)
    - [@minecraft/server-editor](#minecraftserver-editor)
- [ScriptAPIの仕様](#scriptapiの仕様)
    - [JavaScriptの仕様](#javascriptの仕様)
    - [beforeEventsの仕様](#beforeeventsの仕様)
    - [Playerクラスの仕様](#playerクラスの仕様)
- [その他](#その他) 
    - [他ファイルの参照](#他ファイルの参照)
    - [eval関数の利用方法](#eval関数の利用方法)
- [最後に](#最後に)

# はじめに
前回はScriptAPIの始め方ということで投稿しましたが、厳密に情報の説明が出来ていなかった為、今回はそれも兼ね、ScriptAPIの情報を纏めていきたいと思います。

最新バージョンが更新される度に出来るだけ早く更新するように心がけていますが、情報が追い付いていない可能性がありますので、予めご了承ください。

この「ScriptAPI参考書」シリーズではマインクラフト統合版のScriptAPIについて基礎から応用、例文まで詳細に解説し、ScriptAPI開発者や、ScriptAPIの開発を始めようと思っている人の助けになることを目的としています。

また、このシリーズを読むにあたって、ある程度のマインクラフトとJavaScriptの事前知識が必要になってくることがあります。

*注意: このシリーズではMinecraft Bedrock Editionを省略してマインクラフトと表記しています。*

前回: [ScriptAPIの始め方](https://qiita.com/yuki2825624/items/8c3ba7184827d453930e)
次回: [基本的な扱い](https://qiita.com/yuki2825624/items/e62ed10a71d43903bb22)

# モジュールの種類

前回はScriptAPIの`@minecraft/server`について解説しましたが、他にも様々なモジュールがあります。

### @minecraft/server

主に使用するモジュールで、プレイヤーやエンティティ、ワールドの操作を行えます。

- manifest.jsonの詳細 **(安定版)**

```json:manifest.json
{
    "module_name": "@minecraft/server",
    "version": "1.19.0"
}
```

- NPMのバージョン

|種類           |バージョン                    |
|:------------:|:---------------------------:|
|Stable        |1.19.0                       |
|Beta          |2.0.0-beta.1.21.81-stable   |
|Preview Stable|2.0.0-rc.1.21.90-preview.25 |
|Preview Beta  |2.1.0-beta.1.21.90-preview.25|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]**

|種類  |バージョン |詳細                           |
|:----:|:---------:|:-----------------------------:|
|Stable|1.19.0     |-                              |
|Beta  |2.0.0-beta|BetaAPIの有効化が必要          |
|Alpha |3.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー]**

|種類  |バージョン |詳細                           |
|:----:|:---------:|:-----------------------------:|
|Stable|2.0.0     |-                              |
|Beta  |2.1.0-beta|BetaAPIの有効化が必要          |
|Alpha |3.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server/minecraft-server?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server)

### @minecraft/server-ui

マインクラフトのUIを表示の際に使用するモジュールです。以下の様なフォームを表示したり、操作したりすることが出来ます。

![img](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637082/842a6341-230b-cdee-2d1f-56acb935e2a0.png)

- manifest.jsonの詳細 **(安定版)**

```json:manifest.json
{
    "module_name": "@minecraft/server-ui",
    "version": "1.3.0"
}
```

- NPMのバージョン

|種類          |バージョン                   |
|:------------:|:---------------------------:|
|Stable        |1.3.0                        |
|Beta          |2.0.0-beta.1.21.81-stable    |
|Preview Stable|2.0.0-rc.1.21.90-preview.25  |
|Preview Beta  |2.1.0-beta.1.21.90-preview.25|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]**

|種類  |バージョン |詳細                           |
|:----:|:---------:|:-----------------------------:|
|Stable|1.3.0      |-                              |
|Beta  |2.0.0-beta|BetaAPIの有効化が必要          |
|Alpha |3.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー版]**

|種類  |バージョン |詳細                           |
|:----:|:---------:|:-----------------------------:|
|Stable|2.0.0     |-                              |
|Beta  |2.1.0-beta|BetaAPIの有効化が必要          |
|Alpha |3.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server-ui/minecraft-server-ui?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server-ui)

### @minecraft/server-gametest
マインクラフトのGameTest機能を扱う事が出来ます。

- manifest.jsonの詳細 **(安定版)**

```json:manifest.json
{
    "module_name": "@minecraft/server-gametest",
    "version": "0.1.0"
}
```

- NPMのバージョン

|種類          |バージョン                   |
|:------------:|:---------------------------:|
|Stable        |0.1.0                        |
|Beta          |1.0.0-beta.1.21.81-stable   |
|Preview Stable|0.1.0-rc.1.21.40-preview.20  |
|Preview Beta  |1.0.0-beta.1.21.90-preview.23|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|0.1.0      |非推奨               |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|0.1.0      |-                    |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server-gametest/minecraft-server-gametest?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server-gametest)

### @minecraft/server-net
マインクラフトの外部とHTTPベースのリクエストを実行することが出来ます。
BDSサーバーでのみ使用可能な点に注意。

- manifest.jsonの詳細 **(ベータ版)**

```json:manifest.json
{
    "module_name": "@minecraft/server-net",
    "version": "1.0.0-beta"
}
```

- NPMのバージョン

|種類          |バージョン                   |
|:------------:|:---------------------------:|
|Stable        |-                            |
|Beta          |1.0.0-beta.1.21.81-stable    |
|Preview Stable|-                            |
|Preview Beta  |1.0.0-beta.1.21.90-preview.25|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server-net/minecraft-server-net?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server-net)

### @minecraft/server-admin
BDSサーバーの管理をするための機能を扱うことが出来ます。
BDSサーバーでのみ使用可能な点に注意。

- manifest.jsonの詳細 **(ベータ版)**

```json:manifest.json
{
    "module_name": "@minecraft/server-admin",
    "version": "1.0.0-beta"
}
```

- NPMのバージョン

|種類          |バージョン                   |
|:------------:|:---------------------------:|
|Stable        |-                            |
|Beta          |1.0.0-beta.1.21.81-stable    |
|Preview Stable|-                            |
|Preview Beta  |1.0.0-beta.1.21.90-preview.25|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |1.0.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server-admin/minecraft-server-admin?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server-admin)

### @minecraft/server-editor
[Minecraft Editor](https://learn.microsoft.com/en-us/minecraft/creator/documents/editorinstallation?view=minecraft-bedrock-stable)でのエディターの操作を行えます。
Minecraft Editorでのみ使用可能な点に注意

- manifest.jsonの詳細 **(ベータ版)**

```json:manifest.json
{
    "module_name": "@minecraft/server-editor",
    "version": "0.1.0-beta"
}
```

- NPMのバージョン

|種類          |バージョン                   |
|:------------:|:---------------------------:|
|Stable        |-                            |
|Beta          |0.1.0-beta.1.21.81-stable    |
|Preview Stable|-                            |
|Preview Beta  |0.1.0-beta.1.21.90-preview.25|

- 利用可能なmanifest.jsonの最新バージョン **[安定版]** (使用出来るかは未確認)

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |0.1.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

- 利用可能なmanifest.jsonの最新バージョン **[プレビュー版]**

|種類  |バージョン |詳細                 |
|:----:|:---------:|:-------------------:|
|Stable|-          |-                    |
|Beta  |0.1.0-beta |BetaAPIの有効化が必要|
|Alpha |2.0.0-alpha|他モジュールもalphaの使用が必要|

[Document](https://learn.microsoft.com/ja-jp/minecraft/creator/scriptapi/minecraft/server-editor/minecraft-server-editor?view=minecraft-bedrock-experimental) | [npm](https://www.npmjs.com/package/@minecraft/server-editor)

# ScriptAPIの仕様

### JavaScriptの仕様
ScriptAPIはJavaScriptで記述していますが、JavaScriptの中でもESModuleという形式が採用されています。
また、ローカル環境において、ScriptAPIでは標準のAPI、外部のAPIを含めAPIを使用することが出来ません。`fs`や`child_process`がその例です。また、`net`、`http`、`express`モジュールや`fetch`関数が使用できないため、必然的にWebAPIも使用不可となっています。



### beforeEventsの仕様
以下のコードは、ブロックを壊した時に、ブロックを壊したプレイヤーにブロックのIDの名前でタグを付与するものです。

```js:index.js
import { world } from "@minecraft/server";

world.beforeEvents.playerBreakBlock.subscribe((ev) => {
    const { player, block } = ev;
    
    player.addTag(block.typeId);
});
```
しかし、実際に実行してみると、以下の様なエラーが出てしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637082/8c31f1ef-63b2-1afa-5bdc-23c6e78743a1.png)

これは、beforeEventsの仕様によるものです。beforeEventsの処理の際に、ノーディレイで対象（プレイヤーやワールド、ディメンション等）に変化を与えるような関数を呼び出した際にこのエラーが発生してしまいます。

どのように解決すればいいかというと、`system.runTimeout()`などで処理に遅延を与えることで解決できます。上のコードの場合、下記のようにします。`system`をimportしなければならないことに注意してください。

```js:index.js
import { world, system } from "@minecraft/server";

world.beforeEvents.playerBreakBlock.subscribe((ev) => {
    const { player, block } = ev;
    
    system.runTimeout(() => {
        player.addTag(block.typeId);
    }, 0);
});
```
`system.setTimeout`の第二引数は遅延するtick数で、0にすることでほぼノーディレイのままエラーが発生せずに実行できます。

### Playerクラスの仕様
`@minecraft/server`で扱う`Player`クラスは`Entity`クラスの継承で構成されています。そのため、エンティティでは使用できるが、プレイヤーでは使用できないメソッドが存在しています。

以下のメソッドはプレイヤーに対して使用できません。

- `<Player>.remove()`
- `<Player>.clearVelocity()`
- `<Player>.applyImpulse()`

また、以下のメソッドは使用できるものの、プレイヤーに対して効果がありません。

- `<Player>.setRotation()`

# その他

### 他ファイルの参照
通常、コードが短ければ1つのファイルで済むでしょう。ただ、コードが長くなる際、複数のファイルに分けることが必要になる場合があります。

複数のファイルを参照する時のよくある間違いに、`manifest.json`の`modules`の`entry`を増やそうとする方が居ますが、間違いです。
実際にどのようにするかというと、現在`entry`に設定しているファイルで他のファイルを参照する必要があります。

文章だけでは少し分かり辛いので、JavaScriptの他ファイルの読み込み、読み取りの方法を解説していきます。だた、ここではちょっとした例を出すに過ぎないので、詳しく知りたい方は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import)をご確認ください。

まず注意して欲しいのが、ファイルの読み込み、読み取りには`scripts`フォルダ内にファイルが存在している必要があります。

例えば、`test.js`を読み込みたい時、以下の様な階層は誤りです。
```
Sample
┣ scripts
┃ ┗ index.js
┣ test.js
┣ manifest.json
┗ pack_icon.png 
```

このような階層にする必要があります。
```
Sample
┣ scripts
┃ ┣ index.js
┃ ┗ test.js
┣ manifest.json
┗ pack_icon.png 
```

注意点に留意して次に進みます。

このようなコードで`test.js`ファイルを読み込むことができます。
```js:index.js
import "./test.js";
```
`./`とは？と思った方、これは相対パスというパスの表現方法で、この場合同じ階層の`test.js`ファイルを指定しています。詳しくは本題から逸れてしまいますので割愛します。

読み込みだけの場合はこれで十分ですが、他のファイルで関数や変数を用意して置き、読み取ることも出来ます。

以下の様なコードでファイルから読み取ることができます。
```js:index.js
import { random } from "./random.js";
```
```js:random.js
export function random(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
```
読み取るには、読み取り側のファイルの関数、変数の始めに`export`を記述する必要があることに注意してください。

### eval関数の利用方法
[eval()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval)は通常、ScriptAPIにおいて非推奨なため、使用する事が出来ません。しかし、`manifest.json`で設定をすることによって使用することが出来ます。

manifest.jsonに以下の要素を付け足すことにより可能です。
`"capabilities": [ "script_eval" ]`

実際に付け足した例です。
```json:manifest.json
{
    "format_version": 2,
    "header": {
        "name": "Test",
        "description": "ScriptAPI Test Behavior Pack",
        "uuid": "<UUID>",
        "version": [ 1, 0, 0 ],
        "min_engine_version": [ 1, 21, 0 ]
    },
    "modules": [
        {
            "description": " ",
            "type": "script",
            "entry": "scripts/index.js",
            "uuid": "<UUID>",
            "version": [ 1, 0, 0 ]
        }
    ],
    "dependencies": [
        {
            "module_name": "@minecraft/server",
            "version": "1.17.0"
        }
    ],
    "capabilities": [
        "script_eval"
    ]
}
```

# 最後に
今回は、ScriptAPIについての情報を纏めてみました。情報を全て網羅しているわけでは無いので、本記事に載っていない情報を見かけた、若しくは知っているという方は、是非コメント等で情報共有をして頂けると助かります。
今後ともより良い記事を製作していくよう努めますので、何卒よろしくお願いします。