拡張子だけではスキマティック形式は分からない — .schematicファイル33個中31個は別の形式だった
5つの形式、4つの異なるブロックパッキング方法があり、.schematicは2つの形式で共有されています。ファイル名を信用するよりも、NBTルートを嗅ぎ分ける方が確実であることが、実証データで示されています。
流通しているスキマティック形式は5種類あり、ファイル名は事実というよりはヒントに過ぎません。 ここで使われているビューアは、ファイルの中身を見て形式を判断していますが、それには明確な理由があります。
5つの形式、5つの拡張子
| 拡張子 | 形式 |
|---|---|
.nbt | バニラ構造物 |
.schem | スポンジ |
.schematic | スポンジ — デフォルト |
.litematic | Litematica |
.mcstructure | 岩盤 |
問題となる行は.schematicです。この拡張子はクラシックMCEdit形式とスポンジ形式で共有されており、ファイルは知らない人や気にしない人によって名前が変更されることがあります。
実際のコーパスで数えたところ、33個の.schematicファイルのうち、31個がMCEdit、1個がバニラ構造物、1個がLitematicaでした。つまり、拡張子によるデフォルトの推測はほとんどの場合間違っており、2つのファイルは.schematicとは全く関係なく、単に誤った名前が付けられていたのです。
この問題を解決するには、NBTルートを嗅ぎ分け、ファイルが何であるかをファイル名よりも優先させることです。
Regionsキー → Litematicapaletteかつblocks→ バニラ構造物- それ以外はMCEdit形式のテストを行い、それでもだめなら拡張子にフォールバック
同じブロックをパックする4つの方法
形式は見た目だけが異なるわけではありません。それぞれがブロックデータを全く異なる方法で保存しており、それぞれの選択には結果が伴います。
バニラ.nbt — スパースリスト。 配置されたブロックごとに1つのエントリがあり、それぞれがパレットインデックスを指します。空気は単に存在しないため、中空の構造物は安価です。
スポンジ.schem — 可変長整数ストリーム。 パレットインデックスは可変幅整数としてパックされます。1バイトあたり7ビットのペイロードがあり、最上位ビットがセットされている場合は継続します。小さなパレットはブロックあたり1バイトですが、127エントリを超えるパレットでは、高いインデックスに対して2バイトかかります。密ですが、自己記述的です。
MCEdit .schematic — フラットなバイト配列。 ブロックあたり1バイトなので、最大256種類のブロックタイプしか扱えません。そのため、ブロックあたり4ビットで9番目のビットをパックするAddBlocksサイド配列が必要になります。これはブロックステート以前のレガシーな数値ID形式であり、そのIDは名前ではなくSchematicaMapping複合タグを介して解決されます。
Litematica .litematic — ビットパックされたロング。 インデックスは正確にmax(2, bits needed for the palette)ビットずつ、LSBファーストでパックされ、1つのエントリが2つのロングの境界をまたぐことがあります。5エントリのパレットはブロックあたり3ビットを使用し、300エントリのパレットは9ビットを使用します。
2ビットの最小値が重要です。2ブロックのパレットでもエントリあたり2ビット以下には圧縮されないため、モノクロの構造物でも計算が示すほど小さくはなりません。
岩盤はリトルエンディアン
.mcstructureは、より低いレベルで異質な存在です。岩盤はリトルエンディアンNBTで書き込みますが、Javaのすべての形式はビッグエンディアンで書き込みます。これは形式解析が行われる前に決定されます。間違ったエンディアンでバイトを読み取ると、間違った構造が得られるのではなく、全く解析できないゴミが得られます。
これが実際に意味すること
スキマティックがどこかで開かない場合、最初の疑問は「ファイルが破損しているか」ではなく、「このファイルは名前が示すものか」です。ダウンロードページからの.schematicは、スポンジよりもMCEditである可能性がはるかに高く、拡張子を信用するツールは完全に正常なファイルを拒否するでしょう。
同じ構造物の2つのエクスポートを比較する場合、サイズの違いは内容よりも主にエンコーディングに関するものです。中空の構造物のスパースなバニラ.nbtと、同じもののビットパックされた.litematicは、異なる問題を解決しているのです。