The extension does not tell you the schematic format — 31 of 33 .schematic files were something else's guess
Five formats, four different ways of packing blocks, and .schematic is shared by two of them. Sniffing the NBT root beats trusting the filename, with counted evidence.
There are five schematic formats in circulation, and the filename is a hint rather than a fact. The viewer here decides what a file is by looking inside it, and there is a measured reason for that.
Five formats, five extensions
| extension | format |
|---|---|
.nbt | vanilla structure |
.schem | Sponge |
.schematic | Sponge — by default |
.litematic | Litematica |
.mcstructure | Bedrock |
The problem row is .schematic. That extension is shared by the classic MCEdit format and Sponge's, and files get renamed by people who do not know or do not care.
Counted on a real corpus: of 33 .schematic files, 31 were MCEdit, one was a vanilla structure and one was a Litematica. So the extension's default guess is wrong for nearly all of them, and two files were not .schematic in any sense — just misnamed.
The fix is to sniff the NBT root and let what the file is win over what it is called:
- a
Regionskey → Litematica paletteandblocks→ vanilla structure- otherwise the MCEdit shape test, then fall back to the extension
Four ways to pack the same blocks
The formats do not differ cosmetically. Each stores block data in a genuinely different way, and each choice has a consequence:
Vanilla .nbt — a sparse list. One entry per placed block, each naming a palette index. Air is simply absent, so a hollow build is cheap.
Sponge .schem — a varint stream. Palette indices packed as variable-width integers: seven bits of payload per byte, high bit set to continue. Small palettes cost one byte per block; a palette over 127 entries starts costing two for the high indices. Dense, but self-describing.
MCEdit .schematic — a flat byte array. One byte per block, so 256 block types maximum — which is exactly why it needs an AddBlocks side-array packing a ninth bit as a nibble per block. This is a legacy numeric-id format from before block states, and its ids resolve through a SchematicaMapping compound rather than being names.
Litematica .litematic — bit-packed longs. Indices are packed at exactly max(2, bits needed for the palette) bits each, LSB-first, and an entry may straddle the boundary between two longs. A 5-entry palette uses 3 bits per block; a 300-entry one uses 9.
The floor of 2 bits matters: even a two-block palette does not compress below 2 bits per entry, so a monochrome build is not as small as the maths suggests.
Bedrock is little-endian
.mcstructure is the odd one out at a lower level: Bedrock writes little-endian NBT where every Java format writes big-endian. That is decided before any format parsing happens — read the bytes with the wrong endianness and you do not get a wrong structure, you get garbage that fails to parse at all.
What this means practically
If a schematic will not open somewhere, the first question is not "is the file corrupt" but "is this file what its name says". A .schematic from a download page is much more likely to be MCEdit than Sponge, and a tool that trusts the extension will reject a perfectly good file.
And when comparing two exports of the same build, size differences are mostly about encoding rather than content — a sparse vanilla .nbt of a hollow build and a bit-packed .litematic of the same thing are solving different problems.