【マイクラ】コマンドマクロとは?functionのマクロ引数・入力例を解説【Java版】

この記事はJava版のデータパック向けです
統合版(BE)のfunctionとは仕様が異なるため注意してください
コマンドマクロはJava版1.20.2以降で使えるfunctionの機能です

こんにちは。ゆずかきです。

マイクラJava版でデータパックを触っていると、だんだんこう思うことがあります。

「同じようなfunctionを何個も作るの、ちょっと面倒だな…」
「アイテム名や個数だけ変えて、同じ処理を使い回せないかな?」
「スコアボードやstorageの値を、functionの中に差し込めたら便利なのに」

こういう時に使えるのが、今回紹介するコマンドマクロです。

コマンドマクロを使うと、functionに引数を渡して、.mcfunctionの中のコマンドへ値を差し込めます。
例えば、アイテムIDと個数だけを引数で変えて、同じgive処理を使い回す…みたいなことが出来ます。

この記事を読めば、次のことが分かるようになります。

  • Java版のコマンドマクロとは何か分かります👍
  • $(変数名)を使ったfunctionマクロの書き方が分かります
  • {item:"minecraft:diamond",count:3}のような引数入力例が分かります
  • with storageを使ってstorageから値を渡せるようになります
  • Java版1.21以降・1.21.9以降で詰まりやすいフォルダ構成も確認できます

それでは、やっていきましょう!

※本記事はJava版向けです。統合版(BE)では同じ構文で使えません。
※コマンドはワールドに影響を与える可能性があるため、検証用ワールドやバックアップを用意してから試してくださいね。
※ゲーム内の仕様については、Minecraft公式リリースノートおよびコミュニティWikiを参考にしています。


目次

1. コマンドマクロとは
2. 通常のfunctionとマクロfunctionの違い
3. 対応バージョンと注意点
4. まずは最小構成のデータパックを作る
5. マクロ引数の基本構文
6. 入力例①:sayで文字と数字を渡す
7. 入力例②:giveでアイテム名と個数を渡す
8. 入力例③:storageの値からマクロを呼び出す
9. スコアボードの値をマクロ引数に使う方法
10. よくある失敗とチェックポイント
11. コマンドマクロの使いどころ・使わない方がいい場面
12. まとめ
13. 参考文献

この記事で分かること
・Java版のfunctionマクロの基本
・マクロ引数の渡し方
with storageを使った実用例
・1.21以降のデータパック構成で詰まりやすいポイント


1. コマンドマクロとは

コマンドマクロとは、functionの中に後から値を差し込める仕組みです。

普通の.mcfunctionは、書いたコマンドをそのまま実行します。
例えば、下記のように書いた場合、いつ実行してもダイヤモンドが3個だけ渡されます。

give @s minecraft:diamond 3

これでも普通に便利なのですが、もし「ダイヤモンド3個」「エメラルド10個」「パン16個」みたいに、アイテムや個数だけ変えたい場合、毎回functionファイルを増やすのは少し面倒です。

そこでコマンドマクロを使います。

$give @s $(item) $(count)

このように書くと、$(item)$(count)の部分に、function実行時に渡した値を差し込めます。

例えばチャット欄から、次のように実行します。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3}

すると、実行時には下記のようなイメージで処理されます。

give @s minecraft:diamond 3

つまり、同じfunctionを、引数だけ変えて使い回せるということですね。

筆者が最初に触った時は、プログラミングの関数みたいなものをマイクラ内で少し使えるようになった印象でした。
ただし、何でも自由に計算できるわけではなく、あくまでコマンド文字列へ値を差し込む機能として考えると分かりやすいです。


2. 通常のfunctionとマクロfunctionの違い

まず、普通のfunctionとマクロfunctionの違いを整理しておきます。

種類 書き方 特徴
通常のfunction give @s minecraft:diamond 3 毎回同じコマンドを実行する
マクロfunction $give @s $(item) $(count) 実行時に値を差し込める
storage付きマクロ function test:give with storage test:args storageに保存したNBTから値を渡せる


大事なのは、マクロ行には先頭に$を付けるということです。

$give @s $(item) $(count)

$が付いている行だけが、マクロ行として扱われます。
逆に言うと、普通のコマンド行には$を付けません。

say これは普通の行です
$give @s $(item) $(count)
say マクロ実行後の普通の行です

このように、1つのfunctionファイルの中に、普通の行とマクロ行を混ぜることも出来ます。

重要
.mcfunctionファイル内では、基本的にコマンドの先頭に/を付けません。
チャット欄では/giveですが、functionファイル内ではgiveです。

ここは初心者さんがかなり引っかかりやすいので、最初に覚えておきましょう。


3. 対応バージョンと注意点

コマンドマクロは、Java版1.20.2で正式に追加されたfunctionの機能です。
そのため、Java版1.20.1以前では使えません。

また、Java版1.21以降では、データパックのフォルダ名にも注意が必要です。
古い解説では、functionファイルの置き場所がfunctionsになっていることがありますが、Java版1.21以降では基本的にfunctionです。

バージョン帯 マクロ functionフォルダ 注意点
Java版1.20.1以前 × functions コマンドマクロ非対応
Java版1.20.2~1.20.6 functions マクロは使えるが、フォルダ名は旧形式
Java版1.21~1.21.8 function functionsではなく単数形に注意
Java版1.21.9以降 function pack.mcmetamin_formatmax_format形式にも注意

特に注意したいのは、次の2つです。

  • Java版1.21以降は、data/名前空間/function/.mcfunctionを置く
  • Java版1.21.9以降は、pack.mcmetaの形式が変わっている

古いデータパック記事を見ながら作ると、ここで止まりやすいです。

体験談
functionの中身が合っているのに、/function候補に出てこない時は、だいたいフォルダ名かpack.mcmetaが原因です。
コマンド本文を疑う前に、まず読み込み構成を確認しましょう。


4. まずは最小構成のデータパックを作る

ここからは、実際にコマンドマクロを試すための最小構成を作ります。
Java版1.21.11を想定する場合、構成は下記のようにします。

yuzu_macro/
├─ pack.mcmeta
└─ data/
   └─ yuzu_macro/
      └─ function/
         ├─ greet.mcfunction
         ├─ give_item.mcfunction
         └─ from_storage.mcfunction

yuzu_macroの部分は名前空間です。
好きな名前で大丈夫ですが、基本は半角英数字・小文字・アンダーバーで作るのがおすすめです。

pack.mcmetaの例

Java版1.21.11で使うなら、例として下記のようにします。

{
  "pack": {
    "min_format": [94, 1],
    "max_format": [94, 1],
    "description": "yuzu_macro test"
  }
}

Java版1.21.9以降では、pack形式にマイナーバージョンが入り、min_formatmax_formatを使う形になっています。
94.1のような数字をそのまま小数で書くより、[94, 1]のように配列で書く方が分かりやすいです。

ただし、pack形式はバージョンによって変わります。
もしここで詰まった場合は、使っているJava版に対応したpack.mcmetaへ直してください。
Java版1.21.6以降なら、/datapack createで空のデータパックを作れるので、そこから始めるのも安全です。

functionファイルの置き場所

Java版1.21以降では、functionファイルは下記に置きます。

data/yuzu_macro/function/greet.mcfunction

古い記事のように、下記へ置くと読み込まれないことがあります。

data/yuzu_macro/functions/greet.mcfunction

functionsではなく、functionです。
ここは本当に間違えやすいので、何度でも確認しましょう。


5. マクロ引数の基本構文

コマンドマクロの基本は、次の3つです。

  • マクロ行の先頭に$を付ける
  • 差し込みたい場所に$(変数名)を書く
  • /function 名前空間:関数名 {変数名:値}で呼び出す

例えば、functionファイルに次のように書きます。

$say $(message)

そして、チャット欄からこう実行します。

/function yuzu_macro:greet {message:"こんにちは"}

すると、$(message)の部分にこんにちはが入り、実行されます。

引数はNBTの複合タグで渡す

マクロ引数は、{}で囲ったNBTの複合タグとして渡します。

/function yuzu_macro:greet {name:"ゆずかき",count:3}

この場合、渡している値は次の2つです。

変数名 使い道の例
name "ゆずかき" メッセージ内に名前を出す
count 3 数字として個数や回数に使う

必要な引数は全部渡す

function内で$(item)$(count)を使っているなら、呼び出し側でも両方を渡す必要があります。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3}

逆に、余計な値が入っていても、使っていないものは基本的に無視されます。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3,memo:"test"}

この場合、memoをfunction内で使っていなければ、処理には関係しません。

注意
マクロは、値を差し込んだ後のコマンドとして構文チェックされます。
差し込み後に不正なコマンドになると、function全体がスキップされることがあります。


6. 入力例①:sayで文字と数字を渡す

まずは、一番分かりやすいsayで試します。

data/yuzu_macro/function/greet.mcfunctionを作り、下記を入れてください。

$say こんにちは、$(name)さん! 今日のテスト回数は$(count)回です。

チャット欄から実行します。

/function yuzu_macro:greet {name:"ゆずかき",count:3}

これで、namecountの部分が差し込まれて実行されます。

文字列はクォーテーションに注意

呼び出し側では、文字列を""で囲むのが基本です。

/function yuzu_macro:greet {name:"Steve",count:1}

数字は囲まなくて大丈夫です。

/function yuzu_macro:greet {name:"Alex",count:10}

ここで間違えやすいのが、差し込んだ後に成立するコマンドになっているかです。
sayはメッセージとして広く受け取ってくれるので失敗しにくいですが、givetpなどは形式が崩れるとすぐ失敗します。

最初はsayでマクロが動くことを確認してから、他のコマンドへ広げるのがおすすめです。


7. 入力例②:giveでアイテム名と個数を渡す

次は、実用しやすいgiveの例です。
アイテムIDと個数だけを引数で変えられるfunctionを作ります。

data/yuzu_macro/function/give_item.mcfunctionを作り、下記を書きます。

$give @s $(item) $(count)

チャット欄から、ダイヤモンド3個を渡すならこうです。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3}

エメラルド16個ならこうです。

/function yuzu_macro:give_item {item:"minecraft:emerald",count:16}

パン32個ならこうです。

/function yuzu_macro:give_item {item:"minecraft:bread",count:32}

同じgive_item.mcfunctionを使っているのに、渡す引数だけで結果を変えられます。
これがコマンドマクロの便利なところです。

このfunctionで変えられる部分

変えたい内容 引数名 入力例
渡すアイテム item "minecraft:diamond"
渡す個数 count 3
渡す対象 固定で@s 実行者本人

今回は分かりやすくするため、対象は@sで固定しています。
もし対象も変えたいなら、下記のようにすることも出来ます。

$give $(target) $(item) $(count)

呼び出し例です。

/function yuzu_macro:give_target {target:"@a",item:"minecraft:bread",count:5}

ただし、対象セレクターまで引数にすると、入力ミスした時の影響も大きくなります。
最初は@s固定の方が安全です。

注意
マクロは文字を差し込む仕組みなので、危ないコマンドを自由に差し込める形にすると事故の元になります。
配布用データパックでは、何を引数にするかをかなり慎重に決めた方がいいです。


8. 入力例③:storageの値からマクロを呼び出す

コマンドマクロは、チャット欄から直接{item:"minecraft:diamond",count:3}のように渡すだけではありません。
storageに保存した値を使って呼び出すことも出来ます。

これができると、スコアボードや別の処理で作った値を、あとからマクロに渡しやすくなります。

まず、storageに値を入れます。

/data merge storage yuzu_macro:args {give:{item:"minecraft:emerald",count:16}}

次に、storageのgiveという複合タグを使ってfunctionを呼び出します。

/function yuzu_macro:give_item with storage yuzu_macro:args give

これで、giveの中に入っているitemcountが、give_item.mcfunctionへ渡されます。

使っているfunctionは、前章と同じです。

$give @s $(item) $(count)

with storageの考え方

with storageは、下記のようなイメージです。

/function 名前空間:関数名 with storage storage名 パス

今回の例では、こうですね。

/function yuzu_macro:give_item with storage yuzu_macro:args give

yuzu_macro:argsというstorageの中にある、giveという場所を引数として使っています。

storageの中身は、次のようなイメージです。

{
  give: {
    item: "minecraft:emerald",
    count: 16
  }
}

このうち、giveの中身だけをマクロへ渡しているということです。

pathは複合タグを指す必要がある

with storageで指定する場所は、マクロ引数として使える複合タグである必要があります。

良い例です。

{give:{item:"minecraft:emerald",count:16}}

giveの中にitemcountが入っているので、マクロ引数として使えます。

悪い例です。

{give:"minecraft:emerald"}

この場合、giveはただの文字列なので、itemcountを取り出せません。

with storageでうまく動かない時は、まず/data get storageで中身を確認しましょう。

/data get storage yuzu_macro:args

storageの構造が見えるので、どこをpathに指定すればいいか確認しやすくなります。


9. スコアボードの値をマクロ引数に使う方法

スコアボードの値は、そのまま$(count)へ直接入るわけではありません。
一度storageへ保存してから、with storageで渡す流れにすると扱いやすいです。

例として、スコアボードの値をcountとして使い、パンを渡すfunctionを作ってみます。

1. スコアボードを作る

/scoreboard objectives add yuzu_count dummy

2. 自分のスコアをセットする

/scoreboard players set @s yuzu_count 12

3. storageの土台を作る

/data merge storage yuzu_macro:args {give:{item:"minecraft:bread",count:1}}

4. スコアをstorageへ保存する

/execute store result storage yuzu_macro:args give.count int 1 run scoreboard players get @s yuzu_count

5. storageからマクロfunctionを呼び出す

/function yuzu_macro:give_item with storage yuzu_macro:args give

この流れで、countにスコアボードの値が入ります。
上の例だと、countは12になるので、パンが12個渡されます。

スコアボード→storage→マクロの流れ

流れを整理すると、こうです。

  1. スコアボードに数字を入れる
  2. execute store result storageでstorageへ保存する
  3. with storageでfunctionマクロへ渡す
  4. $(count)に数字が差し込まれる

少し回り道に見えますが、データパックを作る時はこの流れがかなり使いやすいです。
特に、計算はスコアボードで行い、最後のコマンド生成だけマクロに任せると整理しやすくなります。

ポイント
マクロは計算そのものをする機能ではありません。
計算はスコアボードやexecute storeで行い、マクロは最後の差し込みに使うと安定します。


10. よくある失敗とチェックポイント

ここからは、コマンドマクロで詰まりやすいポイントをまとめます。
動かない時は、上から順に見てください。

チェックリスト

  • [ ] Java版1.20.2以降で実行しているか?
  • [ ] 統合版(BE)で同じ構文を使おうとしていないか?
  • [ ] Java版1.21以降なのにfunctionsフォルダに置いていないか?
  • [ ] .mcfunction内のコマンド先頭に/を付けていないか?
  • [ ] マクロ行の先頭に$が付いているか?
  • [ ] $(item)など、必要な引数を全部渡しているか?
  • [ ] 引数の文字列を""で囲んでいるか?
  • [ ] with storageで指定したpathが複合タグになっているか?
  • [ ] /reload後にログでエラーが出ていないか?
  • [ ] pack.mcmetaが現在のバージョンに合っているか?

失敗例①:$を付け忘れている

失敗例です。

give @s $(item) $(count)

これだと普通のコマンド行として読み込まれようとするため、$(item)の部分で失敗します。
正しくはこうです。

$give @s $(item) $(count)

マクロ行には、必ず$を付けましょう。

失敗例②:引数が足りない

function内で下記のように書いているとします。

$give @s $(item) $(count)

この時、下記のようにcountを渡し忘れると失敗します。

/function yuzu_macro:give_item {item:"minecraft:diamond"}

正しくはこうです。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3}

マクロ内で使っている変数は、呼び出し側で全部渡してください。

失敗例③:フォルダ名が古い

Java版1.21以降では、これは失敗しやすいです。

data/yuzu_macro/functions/give_item.mcfunction

正しくは、こちらです。

data/yuzu_macro/function/give_item.mcfunction

functionsではなくfunction
これだけで何十分も詰まることがあります。

失敗例④:文字列の扱いが崩れている

例えば、アイテムIDを渡す時は、呼び出し側では文字列として書きます。

/function yuzu_macro:give_item {item:"minecraft:diamond",count:3}

ただし、マクロ行側ではこのように書きます。

$give @s $(item) $(count)

ここを下記のようにしてしまうと、差し込み後のコマンドが崩れることがあります。

$give @s "$(item)" $(count)

giveのアイテムIDとして使うなら、基本は$(item)をそのまま置きます。
逆に、文字列としてNBTやメッセージ内に埋め込みたい時は、コマンドの形式に合わせてクォーテーションが必要になる場合があります。

補足
Java版1.21.5以降では、tellrawtitleなどのテキストコンポーネント周りも新しめの書き方へ変わっています。
古い記事のJSON風の例がそのまま動かないこともあるため、最初はsaygiveのような単純な例で練習すると安全です。


11. コマンドマクロの使いどころ・使わない方がいい場面

コマンドマクロは便利ですが、何でもマクロにすれば良いわけではありません。
向いている場面と、向いていない場面があります。

向いている場面

コマンドマクロが向いているのは、コマンドの形は同じで、一部の値だけ変えたい時です。

例えば、次のような場面です。

  • アイテムIDと個数だけ変えてgiveしたい
  • 座標だけ変えてtpsetblockを使いたい
  • storageに入っている値をコマンドへ差し込みたい
  • 同じ処理を複数パターンで使い回したい
  • スコアボードで計算した数字を、最後にコマンドへ反映したい

こういう処理では、マクロを使うとfunctionファイルが増えすぎにくくなります。

向いていない場面

逆に、次のような場面では無理に使わない方がいいです。

  • 普通のセレクターやスコアボードだけで済む処理
  • 毎tick、毎回違う値で大量に呼び出す処理
  • 引数に自由なコマンド文字列を渡す処理
  • 初心者向け配布データパックで、入力ミスが大事故になる処理

コマンドマクロは、値を差し込んだ後にコマンドとして再評価されます。
通常のfunction行より処理コストが高くなる場面があるため、毎tick大量に使う設計は注意が必要です。

特に、毎回違う引数を入れて大量に実行する処理は、ワールドが重くなる原因になることがあります。

筆者の考え
マクロは「全部を置き換える魔法」ではなく、「最後の1行を柔軟にする道具」と考えると扱いやすいです。
スコア計算や条件分岐はいつも通り作り、最後に必要な値だけマクロで差し込むくらいがちょうどいいです。

最初に覚えるならこの3パターンでOK

初心者さんが最初に覚えるなら、次の3つで十分です。

パターン 使い道
直接引数で呼ぶ /function test:give {item:"minecraft:diamond",count:3} 手動テスト向け
storageから呼ぶ /function test:give with storage test:args give データパック処理向け
スコアをstorageへ入れて呼ぶ execute store result storage ... 数字を連動させる時向け

この3つが分かれば、コマンドマクロの基本はかなり使えるようになります。


12. まとめ

以上、マイクラJava版のコマンドマクロについて、functionのマクロ引数・入力例を解説しました。

要点を整理すると、次の通りです。

  • コマンドマクロは、Java版1.20.2以降で使えるfunctionの機能
  • マクロ行は、先頭に$を付ける
  • 差し込みたい場所には$(変数名)を書く
  • 呼び出しは/function 名前空間:関数名 {変数名:値}で行う
  • storageから呼ぶ場合はwith storageを使う
  • Java版1.21以降はfunctionsではなくfunctionフォルダに注意する
  • Java版1.21.9以降はpack.mcmetamin_formatmax_formatも確認する

コマンドマクロは、最初だけ少し難しく見えます。
でも、実際にやっていることは、function内の一部に値を差し込むというだけです。

まずは、この記事のsaygiveの例をそのまま試してみてください。
そこからstorageやスコアボードと組み合わせると、一気にデータパックで出来ることが広がります。

では、本日はここまでで終わります。
最後までご覧いただき、ありがとうございました。
柚子クラでは他にもJava版コマンド・データパック関係の記事をまとめているので、是非ご覧くださいね(^^♪


13. 参考文献

この記事を書くにあたり、以下の公式リリースノート・コミュニティWikiを参考にしています。