MOBの自然スポーン[]
マインクラフトでは、モンスターや動物などのMOBが減ってくると、プレイヤーの周辺に追加でスポーンするようになっている。このようなスポーンを「自然スポーン」と呼ぶ。自然スポーンの仕組みを解説していく。
自然スポーンのアルゴリズム[]
Minecraft Java Edition 1.9以降[]
種類 | MOB_CONST |
---|---|
モンスター | 70 |
動物 | 10 |
コウモリ | 15 |
イカ | 5 |
- スポーンの手続きを行うチャンク(以下、スポーン対象チャンク)のリストを作る。
- プレイヤーの周辺15×15チャンクの範囲でチャンクのリストを作る。
- 複数のプレイヤーがいる場合、チャンクが重複しないようにリストを作る。
- ワールド境界の外はリストに含めない。
- (筆者の予想で未確認だが、描画範囲外もリストに含めない。)
- MOBの数が上限に引っかからないか確認する。
- 上限の確認は、敵対MOB・中立MOB・コウモリ・イカの4カテゴリそれぞれで行われる。
- それぞれのカテゴリで、対象MOBの総数をAとする。
- B=チャンク数×MOB_CONST÷289 とする。(MOB_CONSTは右表参照)
- A > B であれば次の手続きに進む。
- チャンク数の計算について。
- プレイヤーの周辺17×17チャンクの範囲でチャンクを数える。
- 複数のプレイヤーがいる場合、スポーン対象チャンクリストに含まれているチャンクは重複して数えないが、含まれていないチャンクは重複して数えてしまう。
- スポーン対象チャンクのリスト作成と並行して数えられている。
- スポーン対象チャンクそれぞれについて、スポーンの起点となる座標を抽選する。(一次抽選)
- 手順としては次のようになる。(図1)
- x と z を 0~15 の範囲でランダムに選び、チャンク内水平座標 (x, z) を決定する。
- (x, z) の位置で、太陽光の当たる一番低い y 座標 YheightMap を求める。
- YheightMap を超える最小の 16 の倍数 Ymax を求める。
- y を 0~Ymax-1 の範囲でランダムに選び、チャンク内座標 (x, y, z) を決定する。
- "太陽光が当たる"とは、高度限界からそこまでの間にある全てのブロックが光を完全に透過することである。
- ブロックが"光を完全に透過する"とは、ブロックの性質一覧のページで getLightOpacity が 0 であることである。
- (x, y, z) のブロックが、一次抽選の抽選対象であればそこをスポーン起点として次に進む。
- ブロックが"一次抽選の抽選対象である"とは、ブロックの性質一覧のページで isNormalCube が False であることである。
- 手順としては次のようになる。(図1)
- MOB のスポーンする座標を抽選し(二次抽選)、MOB の種類を抽選する。
- 各スポーン起点に対して、MOB の種類の決定が 3 回行われ、それぞれの MOB のスポーンが 1 回~4 回試される。ただし、1 つのスポーン起点からスポーンする MOB は、通常 4 匹で制限されている。
- 以下を 3 回繰り返す。(MOB 種の切り替えのループ)
- スポーンさせる MOB の種類を未決定の状態にする。
- 以下を 1~4 回のランダムな回数だけ繰り返す。(スポーン試行座標切り替えのループ)
- スポーン起点を中心として 11×1×11 の範囲からランダムにスポーン試行座標を選ぶ。
- 中心に近いところほど選ばれやすい。
- スポーン起点を元に、x軸方向に {(0~5の乱数)-(0~5の乱数)}+0.5、z軸方向に {(0~5の乱数)-(0~5の乱数)}+0.5 ずつずらした場所をスポーン試行座標としている。
- スポーン試行座標がプレイヤーまたは初期スポーン地点から直線距離で 24m 以内なら、次の3.~9.をスキップ。
- スポーンさせる MOB の種類が未決定であれば、スポーン試行座標のバイオームや構造物の条件でスポーン可能なMOBを抽選する。MOB の候補がなければスポーン試行座標切り替えのループを抜けて、MOB 種切り替えのループに戻る。
- 抽選された MOB がスポーン試行座標のバイオームや構造物の条件、床のブロックの条件、簡易的な空間の条件でスポーン可能か確認する。不可能なら次の 5.~9.をスキップ。
- 床のブロックの条件としては、ブロックの性質一覧のページで isFullyOpaque が False、または岩盤、またはバリアブロックであればスポーン不可能。
- 簡易的な空間の条件については調査不十分ですが、スポーン試行座標とその 1 つ上の座標についてブロックの条件を調べているようです。液体・回路系のブロック・レール系のブロックは不適切です。
- MOB ごとの条件と空間の条件でスポーン可能か確認する。不可能なら 6.~9. をスキップ。
- MOB ごとの条件は別にまとめる予定。
- オーバーワールドでの大半のモンスターについて、明るさの条件を抜き出しておきます。
- 暗いほど湧きやすい。自然光の値(SL=0~15)と乱数(RND=0~31)を比較し、SL>RND であればスポーン不可能。続けて、明るさの値(自然光の値に時間帯による補正を加えたもの、またはブロック光の大きい方)と乱数(0~7)を比較し、明るさ>乱数であればスポーン不可能。
- 明るさの値が 8 以上であればスポーン不可能。
- 空間の条件は、MOB のデフォルトのサイズで、液体やブロック、MOBのスポーンを阻害するエンティティなどと重ならないことである。重なればスポーン不可能。
- MOB を初期化する。
- ゾンビやスケルトン、スライム、ゾンビピッグマン、馬、白熊などは大きさが変化することがある。
- 空間の条件を再度確認する。不可能なら8.~9.をスキップ。
- MOB をスポーンさせる。
- スポーン起点に対して実際にスポーンさせた MOB の合計数が、先ほどスポーンさせた MOB ごとに設定されている値(1チャンクに1度にスポーンさせる上限数)以上になっていたら、MOB 種の切り替えのループを抜ける。(次のチャンクのスポーン起点への処理に移る)
- 上限数はたいていの MOB で 4 に設定されている。例外としてガストは 1、馬は 6、オオカミは 8である。
- スポーン起点を中心として 11×1×11 の範囲からランダムにスポーン試行座標を選ぶ。
Minecraft Java Edition 1.7以前[]
筆者が把握している範囲で書きます。動画やスポーンからの引用です。
- 一次抽選について
- Ymaxの計算で、YheightMapではなくLC値というものを使っている。
- LC値の計算には、チャンク内で一番高い位置にある"明るさが0の空気ブロック"でないブロックのy座標Ymaxが使われる。
- LC値は、(Ymaxを超える最小の16の倍数)-1、である。
- LC値は、ワールド作成後に一度決まってしまうと、下げることができないバグが存在していた。→lc値バグとTTとの関係 (ニコニコ動画)
- 一次抽選の対象ブロックは空気ブロック、イカなら水ブロックのみである。
- Ymaxの計算で、YheightMapではなくLC値というものを使っている。
- 二次抽選について
- 二次抽選の範囲はスポーンの起点を中心に41×1×41。
- 1つのスポーン起点に対してMOB種類の抽選は1度しか行われない。
- スポーン場所の抽選は最大で12回まで、実際にスポーンさせた数がMOB毎に決まっている上限数に達するまで行われる。