大雑把なdialogの使い方 (25w21a)


:::note warn
※ **2025.5.20 加筆修正**

minecraft 25w21a での内容です。snapshotのため仕様変更が入る可能性が大いにあります。ご注意ください。
:::

## はじめに
25w20a で追加された `dialog` ですが、これ、すごいです。
自由に選択肢を設定できたり、数値を設定させたりと、自由度が格段に上がります！

間違っている部分もあると思いますが温かく見守ってください。一応サンプルのデータパックを最後に置いています。

## 1. dialog について
`dialog` は datapack で使うことができる新しい内容です。

格納場所は、
`<datapack名>\data\<namespace>\<dialog>` の場所にファイルを `.json` で作成します。

詳しくは [ひろばお氏の解説記事](https://qiita.com/Hirobao1/private/b815bf742d65fe04f857) や [Minecraft Wiki](https://ja.minecraft.wiki/w/Java_Edition_25w20a) を見てください。ここでは必要な部分だけを解説します。
また、Misode氏の [Dialog Generator](https://misode.github.io/dialog/) で簡単に `.json` を作成できるのでこちらを使うことを推奨します。

## 2. dialog のファイルを作成する
dialog には大きく7つのtypeがあります。

- `minecraft:confirmation`
画面下部に yes/no のボタン二つだけのGUI

- `minecraft:dialog_list`
別の dialog に行くための 親dialog。複数表示できる

- `minecraft:multi_action`
一つの選択肢に対し、択一形式でボタンを表示する

- `minecraft:multi_action_input_form`
true/false選択・数値選択・テキスト入力・択一選択式の四つを使った入力ができる

- `minecraft:notice`
ボタン一つだけの、お知らせができる

- `minecraft:server_links`
minecraft:server_linksパケットでサーバーから受信したリンクのリストを、フッターにキャンセルボタンを表示する。(よくわからない)

- `minecraft:simple_input_form`
ユーザー入力を受け入れる選択肢一つのGUI

これらのうち、後述の理由があってショップのGUIなどで使うときは `dialog_list` `multi_action` `multi_action_input_form` が主になると思います。今回は `multi_action` を使います。

```json:
{
    "type": "minecraft:multi_action",
    "title": [],
    "external_title": [],
    "body": [],
    "actions": [
        {
            "label": "",
            "on_click": {
                "action": "run_command",
                "command": ""
            }
        }
        ...
    ],
    "columns": 1,
    "can_close_with_escape": true,
    "on_cancel": {
        "action": "run_command",
        "command": ""
    }
}
```
一つずつ要素を説明していきます。

![title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616358/1285c10f-a232-4ed0-b988-7ff9a7bd514a.png)

- `type`
前述した種類を書きます。

- `title`
図のように、GUIを表示させたときの一番上のテキストを表示します。

- `external_title`
この dialog を選択するためのボタンのテキスト。設定しないと `title` と同じになります。

- `body`
メインの部分のテキスト。`loot_table` などのように `body: []` に要素を加えていくことができ、複数行表示できます。
`type` で `minecraft:plain_message` を指定したら普通通りに文字を表示し、`minecraft:item` を指定すると任意のアイテムを表示させることができます。
`item` の表示幅は `width` `height` ともに 1~256 に制限されています。

- `actions`
押すことができるボタンを設定します。詳しくはこの後で。

- `columns`
一行に並べるボタンの数を設定します。図だと `columns: 1` です。

- `can_close_with_escape`
`esc` で閉じれるかどうかを設定します。基本的に `true` でいい。

- `on_cancel`
選択肢のボタンを押さずに閉じたときの挙動を設定します。

ちなみに、ここに上げた要素はほとんどどのtypeでも共通です。

## 3. dialog のボタンを作成する
```json: 例
        {
            "label": "リンゴ x32",
            "on_click": {
                "action": "run_command",
                "command": "trigger check1 set 10001"
            }
        }, ...
```

表示するテキストは `label` で設定します。
`tellraw` と同じように、ボタンをクリックしたときが `on_click` で、大抵の場合は `"action": "run_command"` になると思います。

その後、`"command"` で押したときのコマンドを設定するのですが、ここでいくつかの問題点が生じています。

#### 問題点1 : 確認画面が表示される
25w20a では、コマンド権限が1以上必要なコマンドについては確認画面が表示されます。この都合上、プレイ体験を低下させないためには `trigger` などを使う必要があります。~~結局面倒~~

#### 問題点2 : 一つしかコマンドを設定できない
~~コマンドを何も設定しないと、ボタンを押したときに自動的に閉じられますが、`give` コマンドなどを設定すると実行された後にまたGUIに戻り閉じません。なので別functionを実行してそこに閉じるコードを書けばいいのですが、実行権限が1以上なので確認画面が表示されてしまいます。~~

~~おそらくコマンド実行権限が1以上のコマンドは実行してもまた元のGUIに戻ってしまう気がします。`say` `trigger` は実行と共に閉じることができたのですが条件は謎です。~~

25w21a にて、権限のレベルに関わらず正式にダイアログが閉じるようになりました。ただ、依然としてコマンドは一つしか実行できず、かつfunction実行時に確認画面が表示されてしまいます。

### クリックした後の処理
ということで、以上の問題点を解決するためには `trigger` を使うのがいいでしょう。

流れとしては、
`trigger <objective> ~` で値を設定させる
↓
`advancement` や `function` で検知をする
↓
本命のコマンドを実行させる
\+ ここに dialog を閉じるコードを組み込む
↓
初期化処理

となると思います。

ちなみに、`dialog` の `.json` を更新した後は<font color=#d94262>**ワールドを開きなおさないと更新されない**</font>ので注意しましょう（n敗）

活用方法としては、もうすでにコマンド勢の方が挙げていらっしゃるように
- NPCとの会話を表現する
- チャット欄には要約を流して、クリックすると全文が見れる
- クエストボード

などいろいろできるかと。可読性も上がって操作も直感的になるので一部に組み込むだけでもクオリティが上がると思います。

## x. 問題点
#### 権限の確認画面が表示される
前述したとおりです。追加されているかつ、dialog には意図的にある程度制限をかけているとのことなのでこの警告がなくなることはおそらくないかな...？と思われます。

#### ソロとマルチで挙動が異なる
`dialog` は、メニュー画面を開いている＝一時停止しているのと同じなので、マルチ（とLANワールド）では一時停止しないので、戦闘中などに表示するのは望ましくないでしょう。

#### 1tick以上の遅延がかかる
`dialog` でトリガーさせたあとにfunctionで検知するので、どうしても遅延が起こってしまいます。なお、ソロプレイの場合は一時停止が起こっているので遅延はない......はずなので、これを使えばソロ専用のマップが作れるかもしれない。


## おわりに
まだまだ解明途中なのでこの記事を踏み台にして発展していくといいなと思います。

ついでに、こんなのができるデータパックを配布しときます。良識の範囲内で改変したり二次配布だったり自由に使ってください。（動画は `multi_action_input_form` ですが、配布版は `multi_action` です）

[ダウンロードはこちらから](https://www.dropbox.com/scl/fi/um94fs4jc0eeze040agws/dialog_buyitem.zip?rlkey=epo0lcuev2j0fxv6z15gnljyu&st=9zi8bcvd&dl=0)

https://x.com/Nofeysan_/status/1923296442006868052