ちかげのひとりごと

ちかげのひとりごと

建築勢向けのmod解説、mod開発のメモ書きなど。

【cocricot】チャンク抜けを修正するmodを作りました

タイトルの通りです。
cocricot等一部のmodpackでまれに発生するチャンク抜け(画像のような現象)の原因を特定し、修正するmodを作成しました。

f:id:chikage125:20210322202033p:plain
こういうやつです

JustEnoughIDsを改変して作成したので、サーバーやminecraftの環境にあるJEIDを入れ替える形で導入してください。

注意点
・公式のJEIDではないので、バグ報告を開発者(DimensionalDevelopment様)に報告するのは控えてください。
・公式のJEIDで発生せず、このJEIDを入れた場合のみ起こるバグは私のtwitterに報告してもらえるとありがたいです。
・このJEIDを入れて、100%チャンク抜けが起こらない保証はできません。継続的なバックアップを強く推奨します。
・このmodを共有する際はこの記事のリンクを共有するようにし、ダウンロードリンクをそのまま貼り付けることは控えて下さい。

ダウンロード
JustEnoughIDs-1.0.3-FixChunkSaving.jar
※ダウンロードできない場合は私のtwitterにお知らせください。

変更履歴
2021-3-23 公開

以下は技術的な話になります。興味のある方だけどうぞ。
cocricot公開から主に内装建築勢の方を困らせてきたチャンク抜け問題でしたが、結論から言うとcocricotのバグではなく、1.12.2のForgeで特定の条件を満たすブロック追加modを入れたときのみに発生するminecraft自体のバグでした。

minecraftでは、16*256*16の範囲のチャンクでワールドを管理しているのは有名な話ですが、実は1チャンクの中にも16*16*16の範囲の更に小さい単位で保存されています。(今回はこれをサブチャンクと呼ぶことにします)

minecraftのブロック保存のシステムとして、1.12.2ではサブチャンク内に存在するブロックの種類の数によって保存方法が変わります。具体的には、
16種類以下 → 線形保存
17種類以上256種類以下 → ハッシュ保存
257種類以上 → レジストリ準拠保存
となります。線形とハッシュ保存については今回は関係ないので解説しません。

ブロックの種類が257種類以上になったときの保存方法であるレジストリ準拠保存ですが、ざっくりいうとブロックの情報を(ID << 4)+damageのインデックスで紐付ける方式になります。したがって、インデックスに入りうる最大の値は (レジストリ内の最大ID+1)*16 となるはずです。ですが、最大値をレジストリのblockstate(柵や階段の形を変えるやつ)の数をもとに登録しているため、本来登録されるべき最大値との間に差異が生まれてしまいます。

ここに、一つのIDにおけるblockstateが少ないブロックを大量に追加すると、レジストリ準拠保存になったときに最大値を超えてしまうブロックがあり、それを置くとエラーが発生し、チャンクが抜けてしまうことになります。

そこでJustEnoughIDsを使ってその部分の処理を正しく記述したものが今回のmodになります。本当は単体のmodで実装したかったのですが、私の技術力が足りず数日格闘した結果諦めることにしました。。w
あとこれはminecraft自体のバグになるので、本来であればForgeにプルリクを送るべきですが、おそらく修正が反映されるより自前でmod作ったほうが早いと思ったのでこの形での公開としました。プルリクは後日送っておきます

なにか質問があればtwitterやコメントで聞いていただければ、私のできる範囲でお答えします。