この記事は JavaEdition 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. ナンバープロバイダーとは
Minecraft Wiki より
ナンバープロバイダー(英: Number provider)は、ランダム値生成やルート文脈の参照などの機能を備えた、ルートテーブルを筆頭にさまざまなデータパックの要素で使用される数値生成機構である。
要するにデータパックで利用できる JSONでの計算 です。
ちなみに...(クリックで表示)
ナンバープロバイダーをコマンドで実行するために
使用するのが /compute コマンドです。
/compute コマンドについては以下の記事で解説しています
この記事を読み終わった後、読むことをオススメします。
計算は、 float でするか、 int でするかを選びます。
int にすれば scoreboard のように整数のみでの計算に、
float なら入力も計算途中も出力も float になり
int を入力に使ったりなどは出来ません。
しかし変換は可能ですし、
「 10 が int なのに対し、10.0 は float として扱える」
ので、 float でも整数は使えます
2. ナンバープロバイダーをやってみよう
2-1. ナンバープロバイダーのファイルの置き場所
データパックのfunctionと同じ階層の
context_float_provider に floatの計算をするJSONファイルを。
context_int_provider に intの計算をするJSONファイルを配置します
data/
└ <名前空間>/
├ function/
├ loot_table/
|
├ context_float_provider/
└ context_int_provider/
ファイル名がIDになります。
例えば
data/compute_test/context_float_provider/add.json なら、
compute_test:add になります
function と同じですね
2-2. ファイルの中身
正直中身をちゃんと書くなら
misode氏の Data Pack Generators の context-float-provider や context-int-provider
を使えば、簡単・正確に書けるので、主にその意味などを解説します
一旦わかりやすさのために例を出します
{
"type": "minecraft:sub",
"left": 10,
"right": 3
}
意外とわかりやすいと思います。
| キー | 意味 |
|---|---|
type |
行う演算 |
left, right
|
入力 |
さっきの例では
left - right
= 10 - 3
をやっていたということです。
入力のキーは、行う演算によって変わります。
以下の表はよく使うと思った type たちです。
これらの意味を名前からも察せる人は多いと思いますが、
とりあえず全部、意味だけでも見ておいていただきたいです
(typeをクリックで説明に飛びます)
| キー名 | この形のtype |
|---|---|
input |
abs, negate, sin, cos, sqrt, floor, ceil, round, truncate, from_int, from_float
|
left, right
|
div, sub, mod, floor_div, floor_mod
|
base, exponent
|
pow |
inputs |
add, mul, min, max, avg, length
|
value |
constant |
target, score, fallback
|
score |
storage, path, fallback
|
storage |
おそらく storage が一番重要です
以下はちょっと特殊なやつ。使い所によってはかなり活躍しそう
| キー名 | この形のtype |
|---|---|
min, max
|
uniform |
n, p
|
binomial |
distribution |
weighted_list |
condition, on_true, on_false
|
conditional |
cases, default
|
number_dispatcher |
attribute |
environment_attribute |
amount |
enchantment_level |
input 系は入力が1つです。絶対値や丸め、三角関数などです
left, right 系は入力が2つで、順番があります。引き算や割り算などです
pow(べき乗)だけは base(基数) と exponent(指数)とキー名が変化します
inputs 系は入力が何個でも書けます。足し算、掛け算、最小 / 最大などです
ただし1個以上は必要で、空にするとデータパックの読み込み時に問題として報告されます
(空のまま使われたときの値は、各種類の解説に書いています)
省略できるキーの値は、各種類の解説に「省略時」として書いています
計算の途中で計算エラー(0除算、int の範囲超えなど)が出る場合
- 後述の
/computeならコマンドが失敗します - それ以外(
LootTableや後述の/data ... compute)なら計算結果が 0になります
floatの最終出力が Infinity / -Infinity / NaNのときも同じです。
結果を入力にもできるので、(1.5 + 2.5) ÷ 2 は以下のように書けます
{
"type": "minecraft:div",
"left": {
"type": "minecraft:add",
"inputs": [1.5, 2.5]
},
"right": 2
}
更に他のナンバープロバイダーの結果を入れたいときは
数値を書くところにIDを書くことで可能です
{
"type": "minecraft:mul",
"inputs": [
"compute_test:hoge",
10,
{
"type": "minecraft:div",
"left": "compute_test:hoge",
"right": 4
}
]
}
hogeの結果は 2.0 なので、2.0 × 10 × (2.0 ÷ 4) = 10.0 になります。
同じ計算を何度も使うときは、ファイルに分けておくと楽です。
2-3. 種類ごとの解説
abs
絶対値です。inputの絶対値を返します。
JSON例(クリックで表示)
{
"type": "minecraft:abs",
"input": -4.5
}
結果 : 4.5
ちなみに...(クリックで表示)
int で -2147483648 を入れると、intの範囲を超えてエラーなり、0になったりします
ちょっと面白い
negate
符号反転です。
JSON例(クリックで表示)
{
"type": "minecraft:negate",
"input": 2.5
}
結果 : -2.5
sin / cos
float専用
正弦 / 余弦です。単位は度ではなく、ラジアンです。
JSON例(クリックで表示)
{
"type": "minecraft:sin",
"input": 1.5707964
}
結果 : 1
tan(正接)を計算したい場合は三角関数の相互関係から計算できます
JSON例(クリックで表示)
$\tan\theta = \frac{\sin\theta}{\cos\theta}$
から
{
"type": "minecraft:div",
"left": {
"type": "minecraft:sin",
"input": 0.785398
},
"right": {
"type": "minecraft:cos",
"input": 0.785398
}
}
結果 : 0.99980825(約 1)
sqrt
float専用
平方根です。負の数はNaNになります。
JSON例(クリックで表示)
{
"type": "minecraft:sqrt",
"input": 9
}
結果 : 3
floor
float専用
負の無限大方向へ丸めた整数を、float として返します。
JSON例(クリックで表示)
{
"type": "minecraft:floor",
"input": 3.9
}
結果 : 3.0
{
"type": "minecraft:floor",
"input": -1.1
}
結果 : -2.0
ceil
float専用
正の無限大方向へ丸めた整数を、float として返します。
JSON例(クリックで表示)
{
"type": "minecraft:ceil",
"input": 3.1
}
結果 : 4.0
{
"type": "minecraft:ceil",
"input": -1.1
}
結果 : -1.0
round
float専用
最近接丸めした整数を、float として返します。
JSON例(クリックで表示)
{
"type": "minecraft:round",
"input": 1.5
}
結果 : 2.0
{
"type": "minecraft:round",
"input": -1.5
}
結果 : -1.0
truncate
float専用
0方向へ丸めた整数を、floatとして返します。
JSON例(クリックで表示)
{
"type": "minecraft:truncate",
"input": 3.9
}
結果 : 3.0
{
"type": "minecraft:truncate",
"input": -1.1
}
結果 : -1.0
from_int
float専用
int を float に変換します
scoreboardを小数計算する場合、必須です
JSON例(クリックで表示)
実行エンティティのcompute_testスコアをfloatプロバイダーに変換
{
"type": "minecraft:from_int",
"input": {
"type": "minecraft:score",
"target": "this",
"score": "compute_test"
}
}
from_float
int専用
float を int に変換します
0方向へ丸めます。int に収まらない値と Infinity / NaN はエラーになります
JSON例(クリックで表示)
10 ÷ 3の結果をintに変換
{
"type": "minecraft:from_float",
"input": {
"type": "minecraft:div",
"left": 10,
"right": 3
}
}
10 / 3 の float は 3.333... で、 int に変換し、 3 になります。
div
割り算です。left ÷ rightです。
-
float… 普通の小数の割り算 -
int… 0方向への丸めの整数除算
right が 0 のとき
-
int… エラー -
float…Infinity/-Infinity/NaN(最終出力ならエラー)
JSON例(クリックで表示)
{
"type": "minecraft:div",
"left": 10,
"right": 3
}
結果 : 3.3333333
sub
引き算です。left - rightです。
JSON例(クリックで表示)
{
"type": "minecraft:sub",
"left": 10,
"right": 3
}
結果 : 7
mod
余りです。left ÷ rightしたときの余りです。
right が 0 のとき
-
int… エラー -
float…NaN(最終出力ならエラー)
JSON例(クリックで表示)
{
"type": "minecraft:mod",
"left": 10,
"right": 3
}
結果 : 1
floor_div
int専用
割り算ですが、divと違って結果を 負の無限大方向 に丸めます
JSON例(クリックで表示)
{
"type": "minecraft:floor_div",
"left": -10,
"right": 3
}
結果 : -4
floor_mod
int専用
余りを求める演算ですが、floor_divと同じで、商を 負の無限大方向 に丸めます
(もちろん、 mod と結果が変わる可能性もあります)
JSON例(クリックで表示)
{
"type": "minecraft:floor_mod",
"left": -10,
"right": 3
}
結果 : 2
pow
冪乗です。baseのexponent乗です
float では $0^0$ は NaN
int では $0^0$、負の指数、結果が int に収まらない場合はエラーです
JSON例(クリックで表示)
$2^{10}$
{
"type": "minecraft:pow",
"base": 2,
"exponent": 10
}
結果 : 1024
add
足し算です。inputs の合計を返します。
inputs が空なら 0
JSON例(クリックで表示)
{
"type": "minecraft:add",
"inputs": [1.5, 2.5, 3]
}
mul
掛け算です。inputsを全部掛けます。
inputs が空なら 1
JSON例(クリックで表示)
{
"type": "minecraft:mul",
"inputs": [2, 3, 4]
}
結果 : 24
min / max
inputs内の最小 / 最大です。
JSON例(クリックで表示)
{
"type": "minecraft:min",
"inputs": [3, 1, 2]
}
結果 : 1
ちなみに...(クリックで表示)
inputs が空のときは、min は 最大値、max は 最小値 を返します。
min が返す値 |
max が返す値 |
|
|---|---|---|
int |
2147483647 |
-2147483648 |
float |
3.4028235e38 |
-3.4028235e38 |
avg
inputsの平均です。
-
float… 普通の平均 -
int… 合計してから、0方向への整数除算
inputs が空だと 0 ÷ 0 になり、int はエラー、float は NaN(最終出力ならエラー)
JSON例(クリックで表示)
{
"type": "minecraft:avg",
"inputs": [1, 2, 3]
}
結果 : 2
length
float専用
inputs をベクトルの成分と見て、その長さを返します。
inputs が空なら 0
JSON例(クリックで表示)
{
"type": "minecraft:length",
"inputs": [3, 4]
}
$\sqrt{x^2+y^2 + ...}$
から
結果 : 5
constant
定数です。数値だけ書いても、これと同じ意味になります。
-
value… 返す値
JSON例(クリックで表示)
{
"type": "minecraft:constant",
"value": 1.5
}
もしくは単に
1.5
でも可能です
score
int専用
スコアボードの値を取得します
float として使いたいなら、from_int を使用します
-
target… 誰のスコアか。次のどちらか- 文脈のエンティティを略記 …
"this"や"target_entity" - オブジェクト
-
type: context… 文脈のエンティティ。targetに上と同じID -
type: fixed… 名前で指定。nameにスコアホルダー名
-
- 文脈のエンティティを略記 …
-
score… オブジェクト名 -
fallback… スコアが無いとき(targetの文脈が無いときも)の値。intのプロバイダーで、省略時は0
JSON例(クリックで表示)
{
"type": "minecraft:score",
"target": "this",
"score": "compute_test"
}
{
"type": "minecraft:score",
"target": {
"type": "minecraft:fixed",
"name": "#dummy"
},
"score": "compute_test"
}
スコアをfloatで3分割するなら...
{
"type": "minecraft:div",
"left": {
"type": "minecraft:from_int",
"input": {
"type": "minecraft:score",
"target": {
"type": "minecraft:fixed",
"name": "#dummy"
},
"score": "compute_test"
}
},
"right": 3
}
storage
storage から数値を読みます。
パスに当たるタグが1個の数値でないときはfallback(省略時は0)になります
数値タグが違う場合(intをfloatとして読む、など)は変換されます
-
storage… ストレージのID -
path… NBTパス -
fallback… 取れなかったときの値。ナンバープロバイダーも書けます。省略時は0
JSON例(クリックで表示)
{
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "x"
}
uniform
min 〜 max の乱数です。
min のほうが大きい場合は min が出力されます。
JSON例(クリックで表示)
{
"type": "minecraft:uniform",
"min": 0,
"max": 10
}
binomial
int専用
-
p... 成功確率(float)- 範囲は
0~1 -
0未満は0、1より大きい場合は1で、無限・非数はエラー
- 範囲は
-
n... 試行回数(int)-
0未満は0になります
-
p の確率で成功するものを n 回試行し、その成功回数を出力します
(つまり二項分布の乱数)
JSON例(クリックで表示)
{
"type": "minecraft:binomial",
"n": 10,
"p": 0.5
}
weighted_list
重み付きで、候補のどれかを選びます。
「重み」の解説はJSON例と一緒に書いています
-
distribution… 候補のリスト。空にはできません-
data… その候補のプロバイダー -
weight… 重み。0以上の整数
-
JSON例(クリックで表示)
{
"type": "minecraft:weighted_list",
"distribution": [
{
"weight": 10,
"data": 1
},
{
"weight": 3,
"data": 10
},
{
"weight": 1,
"data": {
"type": "minecraft:storage",
"storage": "compute_test:_",
"path": "atari"
}
}
]
}
「重み」とは端的に言うなら「比率」です
上のJSON例では weight (重み)が上から
10 : 3 : 1 の割合になっていると言うことになります。
比率なので、合計が 1 や 10 や 100 などにする必要はありません
この場合、10 + 3 + 1 = 14 なので
- $10 ÷ 14 ≒ 0.71$ つまり 約71%の確率で
1が返され - $3 ÷ 14 ≒ 0.21$ つまり 約21%の確率で
10が返され - $1 ÷ 14 ≒ 0.07$ つまり 約7%の確率で
compute_test:_というstorageの"atari"が返されます
conditional
predicate を使用し、値を切り替えます。
-
condition…predicate(IDでもインラインでもOK) -
on_true…trueの時の値 -
on_false…falseの時の値。省略時は0
JSON例(クリックで表示)
{
"type": "minecraft:conditional",
"condition": {
"condition": "minecraft:weather_check",
"raining": true
},
"on_true": 2,
"on_false": 1
}
結果 : 雨なら 2、雨でなければ 1
{
"type": "minecraft:conditional",
"condition": {
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"flags": {
"is_sneaking": true
}
}
},
"on_true": {
"type": "minecraft:storage",
"storage": "compute_test:in",
"path": "sneak_bonus"
}
}
結果 : スニーク中なら compute_test:in の sneak_bonus、それ以外は 0
number_dispatcher
conditionalの複数版
cases を上からチェックして、最初に true になったものを返します
どれも通らなければ default(省略時は0)
-
cases-
condition…predicate -
value… そのときのプロバイダー
-
-
default… どれも通らなかったとき。省略時は0
JSON例(クリックで表示)
{
"type": "minecraft:number_dispatcher",
"cases": [
{
"condition": "namespace:is_night",
"value": 2
},
{
"condition": "namespace:is_rain",
"value": 1.5
}
],
"default": 1
}
結果 : 夜なら2, 夜ではなく雨なら1.5, 夜でもなく雨でもないなら1
(predicateは省略しています)
environment_attribute
float専用
ゲーム内の「環境属性」の値を読みます。
-
attribute… 環境属性のID。数値として読めるものだけ指定できます
使える属性は環境属性のほうの話になるので、あんまり書きません
JSON例(クリックで表示)
太陽の角度(float)
{
"type": "minecraft:environment_attribute",
"attribute": "minecraft:visual/sun_angle"
}
空の明るさを int として使う
{
"type": "minecraft:from_float",
"input": {
"type": "minecraft:environment_attribute",
"attribute": "minecraft:gameplay/sky_light_level"
}
}
環境属性についてもう少し詳しく(クリックで表示)
ガッツリは書きません
環境属性は、ディメンションやバイオームごとに決まる設定値で、太陽の角度、雲の高さ、空の明るさなどがあります。
数値として読めるのは、visual/sun_angle(太陽の角度)、visual/cloud_height(雲の高さ)、gameplay/sky_light_level(空の明るさ)のような数値の属性です。
真偽値・色などの属性は指定できません。
環境属性には、場所によって値が変わるもの(位置依存)と、場所に関係なく決まるものがあります。
- 位置依存の属性は、
origin(/computeなら実行位置)の場所の値を読みます -
originが無い状態で位置依存の属性を読んだときは、その属性のデフォルト値になります
enchantment_level
float専用
エンチャントのレベルに応じて値が変わります
カスタムエンチャントの効果の数値で使う「レベル依存値」と同じ書き方をします。
/compute などにはこのパラメーターを設定できないので、エンチャントの定義(カスタムエンチャント)でしか使えません
-
amount… レベル依存値。数値だけ書くと定数で、typeを書くとより詳しく書けますが、ここでは解説しません
JSON例(クリックで表示)
{
"type": "minecraft:enchantment_level",
"amount": {
"type": "minecraft:linear",
"base": 1,
"per_level_above_first": 1
}
}
レベル1なら 1、レベル2なら 2、レベル3なら 3
(/compute ではレベル 0 なので 0 になります)
3. おわりに
この記事は元々、以下の記事に組み込まれる予定でしたが、/compute 以外にも使用しますし、何より長くなってしまったので別記事にしました。
指摘、質問など至らぬところがございましたら、ぜひコメントしていただければ幸いです。
ご清覧ありがとうございました。