はじめに
最初のエリトラ入手までの道のりは険しい。敵がほぼないとはいえエンドの空中をひたすら進まなければならない。
ワールドのシードが分かればローカルで同じワールドを作りスペクテイターで飛び回って最寄りのエンドシティを探せばいいが、それでもできればどのあたりを探せば見つかる可能性が高いかを知っておきたいものである。
シードが不明な場合は自分の足で歩き回ることになるので、なおさら目星は着けておきたい。
そこで例によってMCPを参照してエンドシティの生成アルゴリズムを調べた。
環境
- Minecraft 1.12.2 Java Edition
- forgeSrc-1.12.2-14.23.4.2705
調査
類似のことを次の記事で行っているので、共通する説明は省略する。
- Minecraft 1.12.2 村の座標決定部分のアルゴリズム - Qiita https://qiita.com/MirrgieRiana/items/0a3baee86bb661dc5f99
- Minecraft 1.12.2 ネザー要塞のスポーン座標決定のアルゴリズム - Qiita https://qiita.com/MirrgieRiana/items/e01a3db6fd7bf183fbbb
生成チャンク座標の決定
あるチャンクにエンドシティが生成されるか否かは次のメソッドが与えている。
net.minecraft.world.gen.structure.MapGenEndCity.canSpawnStructureAtCoords
該当部分のコードは大体次のようなものである。
boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
{
// (1)
int chunkX2 = chunkX;
int chunkZ2 = chunkZ;
if (chunkX2 < 0) chunkX2 -= 19;
if (chunkZ2 < 0) chunkZ2 -= 19;
int regionX = chunkX2 / 20;
int regionZ = chunkZ2 / 20;
// (2)
Random random = world.setRandomSeed(regionX, regionZ, 10387313);
int chunkXExpected = regionX * 20 + (random.nextInt(9) + random.nextInt(9)) / 2;
int chunkZExpected = regionZ * 20 + (random.nextInt(9) + random.nextInt(9)) / 2;
// (3)
if (chunkX == chunkXExpected && chunkZ == chunkZExpected) {
// (4)
if (endProvider.isIslandChunk(chunkX, chunkZ)) {
if (getYPosForStructure(chunkX, chunkZ, endProvider) >= 60) {
return true;
}
}
}
return false;
}
大まかには村と同じで、(1)でチャンク座標が所属する地域座標を求め、(2)でその地域においてエンドシティが生成される場所を求め、(3)で指定チャンクが想定位置か否かを判定している。その後(4)では追加でそこがちゃんとした地形かどうかを判断している。
村との大きな違いは(2)の(random.nextInt(9) + random.nextInt(9)) / 2
である。エンドシティでは(0~8の乱数 + 0~8の乱数) / 2
だが、distance=20の村では0~11の乱数
となる。これによって、生成チャンク座標は20で割った余りが8を中心に偏った分布となる。
この偏りはXZ両方にかかるので、1個の地域に注目すると次のような確率分布となる。
地域のサイズは20なのでF3のチャンク座標表示から目視で判断しやすい。エンドシティが生成されるチャンクXZ座標は下2桁がだいたい8, 28, 48, 68, 88周辺である(座標がともに正の場合)。
これがタイル状に並ぶので、エンドシティもある程度規則正しく並ぶことになる。エンドシティを1個見つけたら座標軸に沿って320m移動すると、そこがちゃんとした土地なら近辺にエンドシティが見つかる可能性が高い。
座標が負の場合の扱いはよくわからないが、1個見つけたら同じ象限では網目状に並ぶはずである。
エンドシップの生成
エンドシップが本当にエンドシティに紐づいているか疑問だったのでコードを調べたが、どうやらエンドシップはエンドシティの部屋の一つとして扱われているらしい。それを実証するかのように、エンドシティではエンドシップが存在する方向に向かって廊下が途切れている。
このゲートのような構造物は普通はその先に癒着するように部屋が生成され目立たなくなるが、船が生成された場合は何もくっついて生成されないためこのように"船着き場"のような特徴的な形になる。船と船着き場が微妙に1マスずれてるけどいいんか
船はエンドシティに伴って出現し、エンドシティが船を伴うか否かはエンドシティの構造の解析になるため単純には予測できない。そのためシード不明世界でエリトラを入手するのに利用できる知識は上記の確率分布までである。しかし目的の座標に移動してもそこが安定した地形であるか否かガチャと船が生成されるかガチャをしなければならないため実際には結構厳しい。