この記事は JavaEdition 26.3 にて動作確認を行っています
データパック及びコマンドにある程度の知識があることを前提としています
指摘や質問などを、軽い気持ちでぜひコメントしていってください!
Minecraft Wiki-ナンバープロバイダー / Minecraft Wiki-コマンド/compute
Minecraft 26.3 Snapshot 10 / Minecraft 26.3
を元に話を進めます。必須ではないですが、よければこちらも合わせてお読みください
0. 事前知識
-
intもしくはinteger- 整数のこと
- マイクラ内では
-2,147,483,648〜2,147,483,647(32bit整数) - 由来は「整数」の英訳から
-
float- 小数のこと。(正しくは単精度浮動小数点数)
- 由来は「浮動」の英訳から
切り捨ての方法がわからない場合(クリックで表示)
- 0方向への丸め
- 小数を、数直線上の0に近づく側の整数にします
- 小数部分を捨てる。と考えていいと思います
- 負の無限大への丸め(別名 床関数)
- 小数を、より小さい側の整数にします
- 正の無限大への丸め
- 小数を、より大きい側の整数にします
- 最近接丸め
- 四捨五入...と言いたいですが、
- 四捨五入では
-1.5 → -2.0なのに対し、最近接丸めでは-1.5 → -1.0です
| 入力 | 0方向への丸め | 負の無限大への丸め | 正の無限大への丸め | 最近接丸め |
|---|---|---|---|---|
| 3.9 | 3 | 3 | 4 | 4 |
| -1.1 | -1 | -2 | -1 | -1 |
1. そもそもcomputeとは? + その他歴史
compute(日: 計算する)コマンドとは何なのでしょうか?
おそらくこの記事を見てる人は、解説しなくていいと思いますが、一応します
(不要な方は飛ばしてください)
computeコマンドは
- 簡単に言うなら 小数点計算 をするコマンドです
- 正確に言うなら ナンバープロバイダー をコマンドから直接実行できるようにするもの
(ナンバープロバイダーについては次で解説します)
何が嬉しいのかというと、小数の計算が公式にできるようになった ことです。
(あと、何より高速です)
今まで用意されていたscoreboardを使った計算では 整数 しか取り扱えませんでした。
そこで小数点計算をする場合、次のように無理やり行っていました。
-
scoreboardで倍率をかけるなどして、整数として扱う - display系エンティティの
transformationを使い、ハック的に計算する- 例: KMFloatOp
-
floatを整数に分解して、整数演算だけで浮動小数点を再現する- 例: FloatCalc
これらの方法についての解説(クリックで表示)
-
スコアボードで倍率をかけるなどして、整数として扱う
スコアボードは整数だけです。
なので1.23などをそのまま入れることはできませんそこで倍率をかけ、(例えば 1000倍)して持っておきます
1.234→1234として扱い、表示するときやNBTに戻すときに、また1000で割ります
(execute store resultのscaleや、data getの倍率)。これで計算はできます。ただし、
- 掛け算するたびに桁が増えるので、あとで割らないと、いわゆるオーバーフローを起こす
- 割り算は余りが捨てられる
- 精度は「何倍したか」で決まり、1000倍なら、だいたい小数第3位までしか保証できない
簡単なので一番よく使われていたと思います
-
displayエンティティの
transformationitem_displayなどのtransformationは、ゲーム内部で4x4行列としてfloatのまま 計算されます。
ここに値を代入し、translationやscaleを結果として取得する。という方法です四則演算はできますが、計算用のエンティティが必要だったりと、制約があります。
正直、中身を理解するのはちょっと大変なので、ライブラリに任せるのがオススメです。
-
FloatCalc
NBTの
floatを、符号・指数・仮数に分解した整数配列(IntArray)に変換し
整数のコマンドだけで浮動小数点演算を再現しています。四則演算に加えて、絶対値、逆数、平方根なども実装されています。
ちょっと重いらしい
では、概要が分かったところで、まずはcomputeの中身の要素である ナンバープロバイダー から見ていきます。
2. ナンバープロバイダー
かなり長くなったので、ナンバープロバイダーについては別記事にしました。
以下の記事をご覧ください
ようやくナンバープロバイダーが終わりました...
忘れてませんか?まだ /compute コマンドは始まってません。
もう飽きてるかもしれませんが、もう少しだけお付き合いください!
ではナンバープロバイダーを実際に実行するコマンドに行きます。
3. /computeと/data ... computeの構文
注意事項
計算の途中で計算エラー(0除算、int の範囲超えなど)が出る場合
- 後述の
/computeならコマンドが失敗します - それ以外(
LootTableや後述の/data ... compute)なら計算結果が 0になります
floatの最終出力が Infinity / -Infinity / NaNのときも同じです。
さらに、/compute コマンドは結果として
ナンバープロバイダーは値10を返しました
のように値を必ず 整数に変換してから 表示します
floatで計算しても、表示は整数なので気をつけてください。(もちろん/data ... computeならfloatとして取り出せます)
計算した値がおかしい場合は、これらの問題を疑ってください
3-1. 構文の全体像
compute <文脈> float <ナンバープロバイダー> [<スケール>]
compute <文脈> integer <ナンバープロバイダー>
ナンバープロバイダーを計算し、その結果を返り値として 整数で返します
つまり float の計算をしたい場合、後述する /data ... compute を使用しないといけません
3-2. 文脈指定
ナンバープロバイダーは、計算のときに
「今どこで実行されているか」「誰が実行しているか」
のような情報を求める場合があります。
文脈では、それを与えます
以下の3つから選択します
| 構文 | 渡されるもの |
|---|---|
default |
origin(実行位置)、this_entity(実行エンティティ) |
block |
defaultに加えて、その座標の block_state、あれば block_entity
|
entity |
defaultに加えて、指定したエンティティがtarget_entityとして渡される |
ちなみにコマンドブロックなどから起動し、いわゆる @s が存在しない場合、this_entity は空になります
-
ほとんどの計算
→default -
特定のブロックの状態を計算に含めたり、扱いたい
→block -
@s以外のエンティティを計算に使いたい
→entity
このような使い分けかな、と思います
3-3. ナンバープロバイダー指定
コマンド内の <ナンバープロバイダー> 部分は、以下の3通りの書き方があります
- データパックのナンバープロバイダーのID
- インライン定義
- 定数のみ
それぞれ以下のように書きます
compute default float compute_test:calc
compute default float {type:"add",inputs:[1.5,2.5]}
compute default float 4
3-4. スケール指定
float の時のみ使える倍率です
丸めの 前に 倍率が掛かります
まあ data コマンドとかとほとんど同じですね
3-4. /data ... compute と結果の取り出し
/compute の戻り値は整数で、
execute store result で取得できる値も、丸め後の整数です。
もしスコアに代入したい場合は、data getコマンドと同じようにスケールしましょう。
execute store result score @s calc run compute default float {type:"div",left:10,right:3} 1000
しかしほとんどの人はこう思っているでしょう
「計算途中で float が使えても結果として float が取り出せないと意味がないのでは?」
なら /data ... compute を使いましょう
data modify storage _ _ set compute default float {type:"div",left:10,right:3}
data modify の set や append などの後ろに、さっきの compute コマンドと同じ構文で書くだけです。
これで storage(もちろんentityやblockも可)に3.333... がfloatのまま入ります。
ちなみに スケール は、/data ... compute にはありません。
4. テスト用データパック
確認用のデータパックを用意しました。
ライセンスフリーなので導入し見てみて、改造したりして確認してください
名前空間は compute_test です。
compute_test/
├ pack.mcmeta
└ data/
├ minecraft/tags/function/load.json
└ compute_test/
├ context_float_provider/
│ ├ add.json
│ ├ div.json
│ ├ hp_ratio.json
│ ├ critical_damage.json
│ ├ to_radians.json
│ └ tan.json
│
└ function/
├ load.mcfunction
├ setup.mcfunction
├ demo.mcfunction
├ add.mcfunction
├ div.mcfunction
├ hp_ratio.mcfunction
├ critical_damage.mcfunction
└ tan.mcfunction
簡単に試すだけなら、以下を入力するとチャットに結果が出ます
function compute_test:demo
4-1. 足し算
x + y をします
data modify storage compute_test:in x set value 3.0f
data modify storage compute_test:in y set value 4.0f
{
"type": "minecraft:add",
"inputs": [
{
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "x"
},
{
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "y"
}
]
}
以下で結果が表示されます
function compute_test:add
こんなものは scoreboard でもできますが、自分は管理や拡張性のしやすさから こっちのほうが良いと思っています
4-2. 割り算
left ÷ right をします
data modify storage compute_test:in left set value 10.0f
data modify storage compute_test:in right set value 4.0f
{
"type": "minecraft:div",
"left": {
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "left"
},
"right": {
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "right"
}
}
以下で結果が表示されます
function compute_test:div
/data ... compute を使用してるので結果が float のままにできています
4-3. HPの割合
hp ... 現在のHP
max_hp ... 最大HP
として、現在のHPのパーセントを表示します
hp ÷ max_hp × 100
data modify storage compute_test:in hp set value 15.0f
data modify storage compute_test:in max_hp set value 20.0f
{
"type": "minecraft:mul",
"inputs": [
{
"type": "minecraft:div",
"left": {
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "hp"
},
"right": {
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "max_hp"
}
},
100
]
}
以下で結果が表示されます
function compute_test:hp_ratio
4-4 クリティカルを確率で発生させる
「ベースダメージ × クリティカル倍率」を、確率で発生させます。
# ベースダメージを10に設定
data modify storage compute_test:in base_damage set value 10.0f
# クリティカル倍率を1.5に設定
data modify storage compute_test:in crit_multiplier set value 1.5f
# クリティカル確率を30%に設定
data modify storage compute_test:in crit_rate set value 30.0f
{
"type": "minecraft:conditional",
"condition": {
"type": "minecraft:random_chance",
"chance": {
"type": "minecraft:min",
"inputs": [
{
"type": "minecraft:mul",
"inputs": [
{ "type": "minecraft:storage", "storage": "compute_test:in", "path": "crit_rate" },
0.01
]
},
0.8
]
}
},
"on_true": {
"type": "minecraft:mul",
"inputs": [
{ "type": "minecraft:storage", "storage": "compute_test:in", "path": "damage" },
{ "type": "minecraft:storage", "storage": "compute_test:in", "path": "crit_multiplier" }
]
},
"on_false": { "type": "minecraft:storage", "storage": "compute_test:in", "path": "damage" }
}
解説(クリックで表示)
condition内で predicate を書いています。
まず、クリティカル確率を0.01倍し、小数の割合にします
その後、今回は仕様として、クリティカル率を80%以上にしたくなかったので、min で 結果と 0.8 を比べています。
これで、クリティカル確率が80%以上でも80%に固定できます
そしてそれを predicate の random_chance に入れます。
condition は predicate の結果が
-
trueだと、on_true -
falseだと、on_false
の値を返すので
クリティカルの確率の成功の有無で値を変更します。
今回、成功したら、ダメージが1.5倍に
失敗したら、ダメージそのままが返されます
以下で結果が表示されます。
確率なので、何回かやると良いでしょう
function compute_test:critical_damage
4-5 tanを計算する
tanのプロバイダーはありませんが、$\tan\theta = \frac{\sin\theta}{\cos\theta}$ から求められます
# 45度を入力する
data modify storage compute_test:in angle set value 45.0f
sin と cos の入力はラジアンなので、度数からラジアンに変換します
$\frac{\pi}{180} ≒ 0.017453292$ を掛ければいいですね
{
"type": "minecraft:mul",
"inputs": [
{ "type": "minecraft:storage", "storage": "compute_test:in", "path": "angle" },
0.017453292
]
}
最後に$\frac{\sin\theta}{\cos\theta}$です。
{
"type": "minecraft:div",
"left": { "type": "minecraft:sin", "input": "compute_test:to_radians" },
"right": { "type": "minecraft:cos", "input": "compute_test:to_radians" }
}
以下で結果が表示されます。
function compute_test:tan
約1.0が表示されたかと思います
最後にボツになったやつを...(クリックで表示)
三角関数のテストとして作ったのですが、余計なfunctionだったりが増えちゃったので、初学者向けではないと判断し、没になりました。
computeコマンド記事のために張り切って作ったものの思ったより内容が複雑になってしまったのでボツになったやつ.gif pic.twitter.com/ij7o7GqP5a
— ヒコマ (@hikoma0000) November 1, 2026
ここまで見てくれた方限定で一応このデータパックのリポジトリを用意しておきます。
出来は期待しないでください。
5. おわりに
かなり長くなってしまいました。
指摘、質問など至らぬところがございましたら、ぜひコメントしていただければ幸いです。
ご清覧ありがとうございました。